1// __ _____ _____ _____ 2// __| | __| | | | JSON for Modern C++ (supporting code) 3// | | |__ | | | | | | version 3.11.2 4// |_____|_____|_____|_|___| https://github.com/nlohmann/json 5// 6// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me> 7// SPDX-License-Identifier: MIT 8 9#include <benchmark/benchmark.h> 10#include <nlohmann/json.hpp> 11#include <fstream> 12#include <numeric> 13#include <vector> 14#include <test_data.hpp> 15 16using json = nlohmann::json; 17 18////////////////////////////////////////////////////////////////////////////// 19// parse JSON from file 20////////////////////////////////////////////////////////////////////////////// 21 22static void ParseFile(benchmark::State& state, const char* filename) 23{ 24 while (state.KeepRunning()) 25 { 26 state.PauseTiming(); 27 auto* f = new std::ifstream(filename); 28 auto* j = new json(); 29 state.ResumeTiming(); 30 31 *j = json::parse(*f); 32 33 state.PauseTiming(); 34 delete f; 35 delete j; 36 state.ResumeTiming(); 37 } 38 39 std::ifstream file(filename, std::ios::binary | std::ios::ate); 40 state.SetBytesProcessed(state.iterations() * file.tellg()); 41} 42BENCHMARK_CAPTURE(ParseFile, jeopardy, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json"); 43BENCHMARK_CAPTURE(ParseFile, canada, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json"); 44BENCHMARK_CAPTURE(ParseFile, citm_catalog, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json"); 45BENCHMARK_CAPTURE(ParseFile, twitter, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json"); 46BENCHMARK_CAPTURE(ParseFile, floats, TEST_DATA_DIRECTORY "/regression/floats.json"); 47BENCHMARK_CAPTURE(ParseFile, signed_ints, TEST_DATA_DIRECTORY "/regression/signed_ints.json"); 48BENCHMARK_CAPTURE(ParseFile, unsigned_ints, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json"); 49BENCHMARK_CAPTURE(ParseFile, small_signed_ints, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json"); 50 51////////////////////////////////////////////////////////////////////////////// 52// parse JSON from string 53////////////////////////////////////////////////////////////////////////////// 54 55static void ParseString(benchmark::State& state, const char* filename) 56{ 57 std::ifstream f(filename); 58 std::string str((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>()); 59 60 while (state.KeepRunning()) 61 { 62 state.PauseTiming(); 63 auto* j = new json(); 64 state.ResumeTiming(); 65 66 *j = json::parse(str); 67 68 state.PauseTiming(); 69 delete j; 70 state.ResumeTiming(); 71 } 72 73 state.SetBytesProcessed(state.iterations() * str.size()); 74} 75BENCHMARK_CAPTURE(ParseString, jeopardy, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json"); 76BENCHMARK_CAPTURE(ParseString, canada, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json"); 77BENCHMARK_CAPTURE(ParseString, citm_catalog, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json"); 78BENCHMARK_CAPTURE(ParseString, twitter, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json"); 79BENCHMARK_CAPTURE(ParseString, floats, TEST_DATA_DIRECTORY "/regression/floats.json"); 80BENCHMARK_CAPTURE(ParseString, signed_ints, TEST_DATA_DIRECTORY "/regression/signed_ints.json"); 81BENCHMARK_CAPTURE(ParseString, unsigned_ints, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json"); 82BENCHMARK_CAPTURE(ParseString, small_signed_ints, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json"); 83 84 85////////////////////////////////////////////////////////////////////////////// 86// serialize JSON 87////////////////////////////////////////////////////////////////////////////// 88 89static void Dump(benchmark::State& state, const char* filename, int indent) 90{ 91 std::ifstream f(filename); 92 std::string str((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>()); 93 json j = json::parse(str); 94 95 while (state.KeepRunning()) 96 { 97 j.dump(indent); 98 } 99 100 state.SetBytesProcessed(state.iterations() * j.dump(indent).size()); 101} 102BENCHMARK_CAPTURE(Dump, jeopardy / -, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json", -1); 103BENCHMARK_CAPTURE(Dump, jeopardy / 4, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json", 4); 104BENCHMARK_CAPTURE(Dump, canada / -, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json", -1); 105BENCHMARK_CAPTURE(Dump, canada / 4, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json", 4); 106BENCHMARK_CAPTURE(Dump, citm_catalog / -, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json", -1); 107BENCHMARK_CAPTURE(Dump, citm_catalog / 4, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json", 4); 108BENCHMARK_CAPTURE(Dump, twitter / -, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json", -1); 109BENCHMARK_CAPTURE(Dump, twitter / 4, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json", 4); 110BENCHMARK_CAPTURE(Dump, floats / -, TEST_DATA_DIRECTORY "/regression/floats.json", -1); 111BENCHMARK_CAPTURE(Dump, floats / 4, TEST_DATA_DIRECTORY "/regression/floats.json", 4); 112BENCHMARK_CAPTURE(Dump, signed_ints / -, TEST_DATA_DIRECTORY "/regression/signed_ints.json", -1); 113BENCHMARK_CAPTURE(Dump, signed_ints / 4, TEST_DATA_DIRECTORY "/regression/signed_ints.json", 4); 114BENCHMARK_CAPTURE(Dump, unsigned_ints / -, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json", -1); 115BENCHMARK_CAPTURE(Dump, unsigned_ints / 4, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json", 4); 116BENCHMARK_CAPTURE(Dump, small_signed_ints / -, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json", -1); 117BENCHMARK_CAPTURE(Dump, small_signed_ints / 4, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json", 4); 118 119 120////////////////////////////////////////////////////////////////////////////// 121// serialize CBOR 122////////////////////////////////////////////////////////////////////////////// 123static void ToCbor(benchmark::State& state, const char* filename) 124{ 125 std::ifstream f(filename); 126 std::string str((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>()); 127 json j = json::parse(str); 128 129 while (state.KeepRunning()) 130 { 131 json::to_cbor(j); 132 } 133 134 state.SetBytesProcessed(state.iterations() * json::to_cbor(j).size()); 135} 136BENCHMARK_CAPTURE(ToCbor, jeopardy, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json"); 137BENCHMARK_CAPTURE(ToCbor, canada, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json"); 138BENCHMARK_CAPTURE(ToCbor, citm_catalog, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json"); 139BENCHMARK_CAPTURE(ToCbor, twitter, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json"); 140BENCHMARK_CAPTURE(ToCbor, floats, TEST_DATA_DIRECTORY "/regression/floats.json"); 141BENCHMARK_CAPTURE(ToCbor, signed_ints, TEST_DATA_DIRECTORY "/regression/signed_ints.json"); 142BENCHMARK_CAPTURE(ToCbor, unsigned_ints, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json"); 143BENCHMARK_CAPTURE(ToCbor, small_signed_ints, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json"); 144 145////////////////////////////////////////////////////////////////////////////// 146// serialize binary CBOR 147////////////////////////////////////////////////////////////////////////////// 148static void BinaryToCbor(benchmark::State& state) 149{ 150 std::vector<uint8_t> data(256); 151 std::iota(data.begin(), data.end(), 0); 152 153 auto it = data.begin(); 154 std::vector<uint8_t> in; 155 in.reserve(state.range(0)); 156 for (int i = 0; i < state.range(0); ++i) 157 { 158 if (it == data.end()) 159 { 160 it = data.begin(); 161 } 162 163 in.push_back(*it); 164 ++it; 165 } 166 167 json::binary_t bin{in}; 168 json j{{"type", "binary"}, {"data", bin}}; 169 170 while (state.KeepRunning()) 171 { 172 json::to_cbor(j); 173 } 174 175 state.SetBytesProcessed(state.iterations() * json::to_cbor(j).size()); 176} 177BENCHMARK(BinaryToCbor)->RangeMultiplier(2)->Range(8, 8 << 12); 178 179BENCHMARK_MAIN(); 180