mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
2c05f5b1b0
* non-functional benchmarks * Fix typo * various fixes * tweaking --------- Co-authored-by: Daniel Lemire <dlemire@lemire.me> Co-authored-by: Francisco Geiman Thiesen <franciscogthiesen@gmail.com>
142 lines
4.7 KiB
C++
142 lines
4.7 KiB
C++
#include <cassert>
|
|
#include <cstdlib>
|
|
#include <ctime>
|
|
#include <format>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <nlohmann/json.hpp>
|
|
#include <simdjson.h>
|
|
#include <string>
|
|
#include "twitter_data.h"
|
|
#include "nlohmann_twitter_data.h"
|
|
#include "benchmark_helper.h"
|
|
#if SIMDJSON_BENCH_CPP_REFLECT
|
|
#include <rfl.hpp>
|
|
#include <rfl/json.hpp>
|
|
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 <class T> 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<TwitterData>().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;
|
|
} |