Add benchmarks for boost json (#2092)

This commit is contained in:
Ikraduya Edian
2023-12-04 22:33:53 +07:00
committed by GitHub
parent 5541e78402
commit 561ffcd519
9 changed files with 315 additions and 0 deletions
+3
View File
@@ -26,6 +26,9 @@ if (TARGET benchmark::benchmark)
if(TARGET nlohmann_json)
target_link_libraries(bench_ondemand PRIVATE nlohmann_json)
endif()
if(TARGET boostjson)
target_link_libraries(bench_ondemand PRIVATE boostjson)
endif()
endif()
endif()
+11
View File
@@ -21,6 +21,10 @@ SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
#include <nlohmann/json.hpp>
#endif
#ifdef SIMDJSON_COMPETITION_BOOSTJSON
#include <boost/json.hpp>
#endif
// This has to be last, for reasons I don't yet understand
#include <benchmark/benchmark.h>
@@ -33,6 +37,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
#include "json2msgpack/sajson.h"
#endif // SIMDJSON_COMPETITION_ONDEMAND_SAJSON
#include "json2msgpack/nlohmann_json.h"
#include "json2msgpack/boostjson.h"
#include "partial_tweets/simdjson_ondemand.h"
#include "partial_tweets/simdjson_dom.h"
@@ -48,6 +53,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
#if SIMDJSON_COMPETITION_SAX
#include "partial_tweets/nlohmann_json_sax.h"
#endif // SIMDJSON_COMPETITION_SAX
#include "partial_tweets/boostjson.h"
#include "distinct_user_id/simdjson_ondemand.h"
@@ -66,6 +72,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
#if SIMDJSON_COMPETITION_SAX
#include "distinct_user_id/nlohmann_json_sax.h"
#endif // SIMDJSON_COMPETITION_SAX
#include "distinct_user_id/boostjson.h"
#include "find_tweet/simdjson_ondemand.h"
#include "find_tweet/simdjson_dom.h"
@@ -81,6 +88,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
#if SIMDJSON_COMPETITION_SAX
#include "find_tweet/nlohmann_json_sax.h"
#endif // SIMDJSON_COMPETITION_SAX
#include "find_tweet/boostjson.h"
#include "top_tweet/simdjson_ondemand.h"
#include "top_tweet/simdjson_dom.h"
@@ -96,6 +104,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
#if SIMDJSON_COMPETITION_SAX
#include "top_tweet/nlohmann_json_sax.h"
#endif // SIMDJSON_COMPETITION_SAX
#include "top_tweet/boostjson.h"
#include "kostya/simdjson_ondemand.h"
@@ -112,6 +121,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
#if SIMDJSON_COMPETITION_SAX
#include "kostya/nlohmann_json_sax.h"
#endif // SIMDJSON_COMPETITION_SAX
#include "kostya/boostjson.h"
#include "large_random/simdjson_ondemand.h"
#if SIMDJSON_COMPETITION_ONDEMAND_UNORDERED
@@ -130,6 +140,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
#if SIMDJSON_COMPETITION_SAX
#include "large_random/nlohmann_json_sax.h"
#endif // SIMDJSON_COMPETITION_SAX
#include "large_random/boostjson.h"
#include "amazon_cellphones/simdjson_dom.h"
#include "amazon_cellphones/simdjson_ondemand.h"
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#ifdef SIMDJSON_COMPETITION_BOOSTJSON
#include "distinct_user_id.h"
namespace distinct_user_id {
struct boostjson {
bool run(simdjson::padded_string &json, std::vector<uint64_t> &result) {
auto root = boost::json::parse(json);
for (const auto &tweet : root.at("statuses").as_array()) {
result.push_back(tweet.at("user").at("id").to_number<uint64_t>());
if (tweet.as_object().if_contains("retweeted_status")) {
result.push_back(tweet.at("retweeted_status").at("user").at("id").to_number<uint64_t>());
}
}
return true;
}
};
BENCHMARK_TEMPLATE(distinct_user_id, boostjson)->UseManualTime();
} // namespace distinct_user_id
#endif // SIMDJSON_COMPETITION_BOOSTJSON
+30
View File
@@ -0,0 +1,30 @@
#pragma once
#ifdef SIMDJSON_COMPETITION_BOOSTJSON
#include "find_tweet.h"
namespace find_tweet {
struct boostjson {
using StringType=std::string;
bool run(simdjson::padded_string &json, uint64_t find_id, std::string &result) {
auto root = boost::json::parse(json);
for (const auto &tweet : root.at("statuses").as_array()) {
if (tweet.at("id") == find_id) {
result = tweet.at("text").as_string();
return true;
}
}
return false;
}
};
BENCHMARK_TEMPLATE(find_tweet, boostjson)->UseManualTime();
} // namespace find_tweet
#endif // SIMDJSON_COMPETITION_BOOSTJSON
+104
View File
@@ -0,0 +1,104 @@
#pragma once
#ifdef SIMDJSON_COMPETITION_BOOSTJSON
#include "json2msgpack.h"
namespace json2msgpack {
struct boostjson2msgpack {
inline std::string_view to_msgpack(const boost::json::value &root, uint8_t *buf) {
buff = buf;
recursive_processor(root);
return std::string_view(reinterpret_cast<char *>(buf), size_t(buff - buf));
}
private:
uint8_t *buff{};
inline void write_double(const double d) noexcept {
*buff++ = 0xcb;
::memcpy(buff, &d, sizeof(d));
buff += sizeof(d);
}
inline void write_byte(const uint8_t b) noexcept {
*buff = b;
buff++;
}
inline void write_uint32(const uint32_t w) noexcept {
::memcpy(buff, &w, sizeof(w));
buff += sizeof(w);
}
inline void write_string(const std::string & str) {
write_byte(0xdb);
write_uint32(uint32_t(str.size()));
::memcpy(buff, str.data(), str.size());
buff += str.size();
}
inline void recursive_processor(const boost::json::value &element) {
switch(element.kind()) {
case boost::json::kind::array: {
write_byte(0xdd);
const auto &array = element.as_array();
write_uint32(static_cast<uint32_t>(array.size()));
for (const auto &child : array) {
recursive_processor(child);
}
} break;
case boost::json::kind::object: {
write_byte(0xdf);
const auto &object = element.as_object();
write_uint32(static_cast<uint32_t>(object.size()));
for (const auto &child : object) {
write_string(child.key_c_str());
recursive_processor(child.value());
}
} break;
case boost::json::kind::int64:
case boost::json::kind::uint64:
case boost::json::kind::double_:
write_double(element.to_number<double>());
break;
case boost::json::kind::string:
write_string(element.as_string().c_str());
break;
case boost::json::kind::bool_:
write_byte(0xc2 + element.as_bool());
break;
case boost::json::kind::null:
write_byte(0xc0);
break;
default:
printf("unexpected\n");
break;
}
}
};
struct boostjson {
using StringType=std::string;
boostjson2msgpack parser{};
bool run(simdjson::padded_string &json, char *buffer, std::string_view &result) {
auto root = boost::json::parse(json);
result = parser.to_msgpack(root, reinterpret_cast<uint8_t *>(buffer));
return true;
}
};
BENCHMARK_TEMPLATE(json2msgpack, boostjson)->UseManualTime();
} // namespace json2msgpack
#endif // SIMDJSON_COMPETITION_BOOSTJSON
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#ifdef SIMDJSON_COMPETITION_BOOSTJSON
#include "kostya.h"
namespace kostya {
struct boostjson {
static constexpr diff_flags DiffFlags = diff_flags::IMPRECISE_FLOATS;
bool run(simdjson::padded_string &json, std::vector<point> &result) {
auto root = boost::json::parse(json);
for (const auto &point : root.at("coordinates").as_array()) {
result.emplace_back(json_benchmark::point{
point.at("x").to_number<double>(),
point.at("y").to_number<double>(),
point.at("z").to_number<double>()
});
}
return true;
}
};
BENCHMARK_TEMPLATE(kostya, boostjson)->UseManualTime();
} // namespace kostya
#endif // SIMDJSON_COMPETITION_BOOSTJSON
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#ifdef SIMDJSON_COMPETITION_BOOSTJSON
#include "large_random.h"
namespace large_random {
struct boostjson {
static constexpr diff_flags DiffFlags = diff_flags::IMPRECISE_FLOATS;
bool run(simdjson::padded_string &json, std::vector<point> &result) {
auto root = boost::json::parse(json);
for (const auto &point : root.as_array()) {
result.emplace_back(json_benchmark::point{
point.at("x").to_number<double>(),
point.at("y").to_number<double>(),
point.at("z").to_number<double>()
});
}
return true;
}
};
BENCHMARK_TEMPLATE(large_random, boostjson)->UseManualTime();
} // namespace large_random
#endif // SIMDJSON_COMPETITION_BOOSTJSON
+43
View File
@@ -0,0 +1,43 @@
#pragma once
#ifdef SIMDJSON_COMPETITION_BOOSTJSON
#include "partial_tweets.h"
namespace partial_tweets {
struct boostjson {
using StringType=std::string;
bool run(simdjson::padded_string &json, std::vector<tweet<StringType>> &result) {
auto root = boost::json::parse(json);
for (const auto &tweet : root.at("statuses").as_array()) {
const auto &user = tweet.at("user");
auto in_reply_to_status_id = tweet.as_object().if_contains("in_reply_to_status_id")
? tweet.at("in_reply_to_status_id") : boost::json::value();
result.emplace_back(partial_tweets::tweet<StringType>{
tweet.at("created_at").as_string().c_str(),
tweet.at("id").to_number<uint64_t>(),
tweet.at("text").as_string().c_str(),
in_reply_to_status_id.is_null() ? 0 : in_reply_to_status_id.to_number<uint64_t>(),
{
user.at("id").to_number<uint64_t>(),
user.at("screen_name").as_string().c_str()
},
tweet.at("retweet_count").to_number<uint64_t>(),
tweet.at("favorite_count").to_number<uint64_t>()
});
}
return true;
}
};
BENCHMARK_TEMPLATE(partial_tweets, boostjson)->UseManualTime();
} // namespace partial_tweets
#endif // SIMDJSON_COMPETITION_BOOSTJSON
+37
View File
@@ -0,0 +1,37 @@
#pragma once
#if SIMDJSON_COMPETITION_BOOSTJSON
#include "top_tweet.h"
namespace top_tweet {
using namespace simdjson;
struct boostjson {
using StringType=std::string;
bool run(simdjson::padded_string &json, int64_t max_retweet_count, top_tweet_result<StringType> &result) {
result.retweet_count = -1;
boost::json::value top_tweet{};
auto root = boost::json::parse(json);
for (const auto &tweet : root.at("statuses").as_array()) {
int64_t retweet_count = tweet.at("retweet_count").as_int64();
if (retweet_count <= max_retweet_count && retweet_count >= result.retweet_count) {
result.retweet_count = retweet_count;
top_tweet = tweet;
}
}
result.text = top_tweet.at("text").as_string();
result.screen_name = top_tweet.at("user").at("screen_name").as_string();
return result.retweet_count != -1;
}
};
BENCHMARK_TEMPLATE(top_tweet, boostjson)->UseManualTime();
} // namespace top_tweet
#endif // SIMDJSON_COMPETITION_BOOSTJSON