#include #include #include #include #include #include #include #include #include #include "twitter_data.h" #include "nlohmann_twitter_data.h" #include "benchmark_helper.h" #if SIMDJSON_BENCH_CPP_REFLECT #include #include void bench_reflect_cpp(TwitterData &data) { std::string output = rfl::json::write(data); size_t output_volume = output.size(); printf("# output volume: %zu bytes\n", output_volume); volatile size_t measured_volume = 0; pretty_print(1, output_volume, "bench_reflect_cpp", bench([&data, &measured_volume, &output_volume]() { std::string output = rfl::json::write(data); measured_volume = output.size(); if (measured_volume != output_volume) { printf("mismatch\n"); } })); } #endif // SIMDJSON_BENCH_CPP_REFLECT #ifdef SIMDJSON_RUST_VERSION #include "../serde-benchmark/serde_benchmark.h" void bench_rust(serde_benchmark::TwitterData *data) { const char * output = serde_benchmark::str_from_twitter(data); size_t output_volume = strlen(output); printf("# output volume: %zu bytes\n", output_volume); volatile size_t measured_volume = 0; pretty_print(1, output_volume, "bench_rust", bench([&data, &measured_volume, &output_volume]() { const char * output = serde_benchmark::str_from_twitter(data); serde_benchmark::free_string(output); })); } #endif template void bench_simdjson_static_reflection(T &data) { simdjson::builder::string_builder sb; simdjson::builder::append(sb, data); std::string_view p; if(sb.view().get(p)) { std::cerr << "Error!" << std::endl; } size_t output_volume = p.size(); sb.clear(); printf("# output volume: %zu bytes\n", output_volume); volatile size_t measured_volume = 0; pretty_print(sizeof(data), output_volume, "bench_simdjson_static_reflection", bench([&data, &measured_volume, &output_volume, &sb]() { sb.clear(); simdjson::builder::append(sb, data); std::string_view p; if(sb.view().get(p)) { std::cerr << "Error!" << std::endl; } measured_volume = sb.size(); if (measured_volume != output_volume) { printf("mismatch\n"); } })); } void bench_nlohmann(TwitterData &data) { std::string output = nlohmann_serialize(data); size_t output_volume = output.size(); printf("# output volume: %zu bytes\n", output_volume); volatile size_t measured_volume = 0; pretty_print(1, output_volume, "bench_nlohmann", bench([&data, &measured_volume, &output_volume]() { std::string output = nlohmann_serialize(data); measured_volume = output.size(); if (measured_volume != output_volume) { printf("mismatch\n"); } })); } size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) { ((std::string *)userp)->append((char *)contents, size * nmemb); return size * nmemb; } std::string read_file(std::string filename) { printf("# Reading file %s\n", filename.c_str()); constexpr size_t read_size = 4096; auto stream = std::ifstream(filename.c_str()); stream.exceptions(std::ios_base::badbit); std::string out; std::string buf(read_size, '\0'); while (stream.read(&buf[0], read_size)) { out.append(buf, 0, size_t(stream.gcount())); } out.append(buf, 0, size_t(stream.gcount())); return out; } int main() { // Testing correctness of round-trip (serialization + deserialization) std::string json_str = read_file(JSON_FILE); // Loading up the data into a structure. simdjson::ondemand::parser parser; simdjson::ondemand::document doc; if(parser.iterate(simdjson::pad(json_str)).get(doc)) { std::cerr << "Error loading the document!" << std::endl; return EXIT_FAILURE; } TwitterData my_struct; if(doc.get().get(my_struct)) { std::cerr << "Error loading TwitterData!" << std::endl; return EXIT_FAILURE; } // Benchmarking the serialization bench_nlohmann(my_struct); bench_simdjson_static_reflection(my_struct); #ifdef SIMDJSON_RUST_VERSION printf("# WARNING: The Rust benchmark may not be directly comparable since it does not use an equivalent data structure.\n"); serde_benchmark::TwitterData * td = serde_benchmark::twitter_from_str(json_str.c_str(), json_str.size()); bench_rust(td); serde_benchmark::free_twitter(td); #endif #if SIMDJSON_BENCH_CPP_REFLECT bench_reflect_cpp(my_struct); #endif return EXIT_SUCCESS; }