|
@@ -0,0 +1,71 @@
|
|
|
|
|
+// Parse-time micro-benchmark — Phase A v1.10 yyjson swap.
|
|
|
|
|
+//
|
|
|
|
|
+// Compares nlohmann::json::parse against smartbotic::db::parse_to_nlohmann
|
|
|
|
|
+// on a corpus of JSON documents loaded from a file (one document per line).
|
|
|
|
|
+// Not a regression gate — informational, run by hand to capture the
|
|
|
|
|
+// parse-speed delta of the Phase A swap.
|
|
|
|
|
+
|
|
|
|
|
+#include <algorithm>
|
|
|
|
|
+#include <chrono>
|
|
|
|
|
+#include <fstream>
|
|
|
|
|
+#include <iostream>
|
|
|
|
|
+#include <string>
|
|
|
|
|
+#include <vector>
|
|
|
|
|
+
|
|
|
|
|
+#include <nlohmann/json.hpp>
|
|
|
|
|
+
|
|
|
|
|
+#include "json_parse.hpp"
|
|
|
|
|
+
|
|
|
|
|
+int main(int argc, char** argv) {
|
|
|
|
|
+ if (argc < 2) {
|
|
|
|
|
+ std::cerr << "usage: bench_json_parse <path-to-json-corpus>\n"
|
|
|
|
|
+ << " corpus = one JSON document per line\n";
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ std::ifstream f(argv[1]);
|
|
|
|
|
+ if (!f) {
|
|
|
|
|
+ std::cerr << "cannot open " << argv[1] << "\n";
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ std::vector<std::string> docs;
|
|
|
|
|
+ std::string line;
|
|
|
|
|
+ while (std::getline(f, line)) {
|
|
|
|
|
+ if (!line.empty()) docs.push_back(line);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (docs.empty()) {
|
|
|
|
|
+ std::cerr << "empty corpus\n";
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ std::cerr << "corpus: " << docs.size() << " documents\n";
|
|
|
|
|
+
|
|
|
|
|
+ constexpr int kIters = 5;
|
|
|
|
|
+ auto bench = [&](const char* name, auto fn) {
|
|
|
|
|
+ double best = 1e18;
|
|
|
|
|
+ for (int i = 0; i < kIters; ++i) {
|
|
|
|
|
+ auto t0 = std::chrono::steady_clock::now();
|
|
|
|
|
+ size_t sink = 0;
|
|
|
|
|
+ for (const auto& s : docs) {
|
|
|
|
|
+ auto j = fn(s);
|
|
|
|
|
+ sink += j.size();
|
|
|
|
|
+ }
|
|
|
|
|
+ auto t1 = std::chrono::steady_clock::now();
|
|
|
|
|
+ double ms = std::chrono::duration<double, std::milli>(t1 - t0).count();
|
|
|
|
|
+ best = std::min(best, ms);
|
|
|
|
|
+ std::cerr << " " << name << " iter " << i << ": " << ms
|
|
|
|
|
+ << " ms (sink=" << sink << ")\n";
|
|
|
|
|
+ }
|
|
|
|
|
+ return best;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ double nl = bench("nlohmann", [](const std::string& s) {
|
|
|
|
|
+ return nlohmann::json::parse(s);
|
|
|
|
|
+ });
|
|
|
|
|
+ double yy = bench("yyjson ", [](const std::string& s) {
|
|
|
|
|
+ return smartbotic::db::parse_to_nlohmann(s);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ std::cout << "best nlohmann: " << nl << " ms\n";
|
|
|
|
|
+ std::cout << "best yyjson: " << yy << " ms\n";
|
|
|
|
|
+ std::cout << "speedup: " << (nl / yy) << "x\n";
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|