mirror of
https://github.com/nlohmann/json.git
synced 2024-11-23 22:19:02 +08:00
Optimize output vector adapter write (#3569)
* Add benchmark for cbor serialization and cbor binary data serialization * Use std::vector::insert method instead of std::copy in output_vector_adapter::write_characters This change increases a lot the performance when writing lots of binary data.
This commit is contained in:
parent
7d361ec8ef
commit
d4daaa897f
@ -53,7 +53,7 @@ class output_vector_adapter : public output_adapter_protocol<CharType>
|
|||||||
JSON_HEDLEY_NON_NULL(2)
|
JSON_HEDLEY_NON_NULL(2)
|
||||||
void write_characters(const CharType* s, std::size_t length) override
|
void write_characters(const CharType* s, std::size_t length) override
|
||||||
{
|
{
|
||||||
std::copy(s, s + length, std::back_inserter(v));
|
v.insert(v.end(), s, s + length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -14250,7 +14250,7 @@ class output_vector_adapter : public output_adapter_protocol<CharType>
|
|||||||
JSON_HEDLEY_NON_NULL(2)
|
JSON_HEDLEY_NON_NULL(2)
|
||||||
void write_characters(const CharType* s, std::size_t length) override
|
void write_characters(const CharType* s, std::size_t length) override
|
||||||
{
|
{
|
||||||
std::copy(s, s + length, std::back_inserter(v));
|
v.insert(v.end(), s, s + length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include "benchmark/benchmark.h"
|
#include "benchmark/benchmark.h"
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <numeric>
|
||||||
|
#include <vector>
|
||||||
#include <test_data.hpp>
|
#include <test_data.hpp>
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
@ -107,4 +109,63 @@ BENCHMARK_CAPTURE(Dump, small_signed_ints / -, TEST_DATA_DIRECTORY "/regression/
|
|||||||
BENCHMARK_CAPTURE(Dump, small_signed_ints / 4, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json", 4);
|
BENCHMARK_CAPTURE(Dump, small_signed_ints / 4, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json", 4);
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// serialize CBOR
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
static void ToCbor(benchmark::State& state, const char* filename)
|
||||||
|
{
|
||||||
|
std::ifstream f(filename);
|
||||||
|
std::string str((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
|
||||||
|
json j = json::parse(str);
|
||||||
|
|
||||||
|
while (state.KeepRunning())
|
||||||
|
{
|
||||||
|
json::to_cbor(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.SetBytesProcessed(state.iterations() * json::to_cbor(j).size());
|
||||||
|
}
|
||||||
|
BENCHMARK_CAPTURE(ToCbor, jeopardy, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json");
|
||||||
|
BENCHMARK_CAPTURE(ToCbor, canada, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json");
|
||||||
|
BENCHMARK_CAPTURE(ToCbor, citm_catalog, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json");
|
||||||
|
BENCHMARK_CAPTURE(ToCbor, twitter, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json");
|
||||||
|
BENCHMARK_CAPTURE(ToCbor, floats, TEST_DATA_DIRECTORY "/regression/floats.json");
|
||||||
|
BENCHMARK_CAPTURE(ToCbor, signed_ints, TEST_DATA_DIRECTORY "/regression/signed_ints.json");
|
||||||
|
BENCHMARK_CAPTURE(ToCbor, unsigned_ints, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json");
|
||||||
|
BENCHMARK_CAPTURE(ToCbor, small_signed_ints, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json");
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// serialize binary CBOR
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
static void BinaryToCbor(benchmark::State& state)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> data(256);
|
||||||
|
std::iota(data.begin(), data.end(), 0);
|
||||||
|
|
||||||
|
auto it = data.begin();
|
||||||
|
std::vector<uint8_t> in;
|
||||||
|
in.reserve(state.range(0));
|
||||||
|
for (int i = 0; i < state.range(0); ++i)
|
||||||
|
{
|
||||||
|
if (it == data.end())
|
||||||
|
{
|
||||||
|
it = data.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
in.push_back(*it);
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
json::binary_t bin{in};
|
||||||
|
json j{{"type", "binary"}, {"data", bin}};
|
||||||
|
|
||||||
|
while (state.KeepRunning())
|
||||||
|
{
|
||||||
|
json::to_cbor(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.SetBytesProcessed(state.iterations() * json::to_cbor(j).size());
|
||||||
|
}
|
||||||
|
BENCHMARK(BinaryToCbor)->RangeMultiplier(2)->Range(8, 8 << 12);
|
||||||
|
|
||||||
BENCHMARK_MAIN();
|
BENCHMARK_MAIN();
|
||||||
|
Loading…
Reference in New Issue
Block a user