Skip to content

Instantly share code, notes, and snippets.

@willir
Created October 13, 2019 11:01
Show Gist options
  • Save willir/4c97942b26b51ae9c72d21f80e54805a to your computer and use it in GitHub Desktop.
Save willir/4c97942b26b51ae9c72d21f80e54805a to your computer and use it in GitHub Desktop.
Benchmark of rapidjson BasicOstreamWrapper vs BufferedOStreamWrapper.
// To Compile: g++ -O3 -std=c++17 -I${RAPIDJSON_INCLUDE} rapidjson-ostream-wrapper-benchmark.cpp -lbenchmark
#include <sstream>
#include <cstdlib>
#include <memory>
#include <random>
#include <string>
#include <string_view>
#define RAPIDJSON_HAS_STDSTRING 1
#include <rapidjson/bufferedostreamwrapper.h>
#include <rapidjson/ostreamwrapper.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
#include <benchmark/benchmark.h>
class Random {
public:
Random() : gen_(std::make_unique<std::mt19937>(std::random_device{}())) {}
std::string GenStr(size_t len) {
std::string res(len, '\0');
for (size_t i = 0; i < len; ++i) {
const auto id =
std::uniform_int_distribution<size_t>{0, ALPHABET.size() - 1}(*gen_);
res[i] = ALPHABET[id];
}
return res;
}
int64_t GenRandomDouble() {
return std::uniform_real_distribution<double>{-10000, 10000}(*gen_);
}
int64_t GenInt64() { return std::uniform_int_distribution<int64_t>{}(*gen_); }
uint64_t GenUint64() {
return std::uniform_int_distribution<uint64_t>{}(*gen_);
}
private:
static constexpr std::string_view ALPHABET =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'\"";
std::unique_ptr<std::mt19937> gen_;
};
struct Foo {
std::string str;
int64_t num1;
uint64_t num2;
double real_num;
explicit Foo(Random &gen)
: str(gen.GenStr(15)), num1(gen.GenInt64()), num2(gen.GenUint64()),
real_num(gen.GenRandomDouble()) {}
};
static constexpr size_t INPUT_LEN = 10000;
static std::vector<Foo> GenerateInput() {
std::vector<Foo> res;
res.reserve(INPUT_LEN);
Random gen;
for (size_t i = 0; i < INPUT_LEN; ++i) {
res.emplace_back(gen);
}
return res;
}
static std::vector<Foo> GetInput() {
static const std::vector<Foo> input_arr = GenerateInput();
return input_arr;
}
template <typename Writer>
static void Write(const std::vector<Foo> &foo_list, Writer &writer) {
writer.StartArray();
for (const auto &foo : foo_list) {
writer.StartObject();
writer.Key("my_string");
writer.String(foo.str);
writer.Key("my_number1");
writer.Int64(foo.num1);
writer.Key("my_number2");
writer.Uint64(foo.num2);
writer.Key("my_real_number");
writer.Double(foo.real_num);
writer.EndObject();
}
writer.EndArray();
}
static std::string ToStringStringBuffer(const std::vector<Foo> &foo_list) {
rapidjson::StringBuffer ss;
{
rapidjson::Writer<rapidjson::StringBuffer> writer(ss);
Write(foo_list, writer);
}
return ss.GetString();
}
static std::string ToStringOStreamWrapper(const std::vector<Foo> &foo_list) {
std::stringstream ss;
{
rapidjson::OStreamWrapper wrapper(ss);
rapidjson::Writer<rapidjson::OStreamWrapper> writer(wrapper);
Write(foo_list, writer);
}
return ss.str();
}
static std::string
ToStringBufferedOStreamWrapper(const std::vector<Foo> &foo_list) {
std::stringstream ss;
{
rapidjson::BufferedOStreamWrapper<> wrapper(ss);
rapidjson::Writer<rapidjson::BufferedOStreamWrapper<>> writer(wrapper);
Write(foo_list, writer);
}
return ss.str();
}
static void BenchmarkStringBuffer(benchmark::State &state) {
const auto foo_list = GetInput();
for (auto _ : state) {
auto res = ToStringStringBuffer(foo_list);
benchmark::DoNotOptimize(res);
}
}
static void BenchmarkBufferedOStreamWrapper(benchmark::State &state) {
const auto foo_list = GetInput();
for (auto _ : state) {
auto res = ToStringBufferedOStreamWrapper(foo_list);
benchmark::DoNotOptimize(res);
}
}
static void BenchmarkOStreamWrapper(benchmark::State &state) {
const auto foo_list = GetInput();
for (auto _ : state) {
auto res = ToStringOStreamWrapper(foo_list);
benchmark::DoNotOptimize(res);
}
}
BENCHMARK(BenchmarkStringBuffer);
BENCHMARK(BenchmarkBufferedOStreamWrapper);
BENCHMARK(BenchmarkOStreamWrapper);
BENCHMARK_MAIN();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment