Skip to content

Commit

Permalink
Added first draft for simple JSON benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
liuzicheng1987 committed May 8, 2024
1 parent 04ce783 commit add67da
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 1 deletion.
10 changes: 9 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
cmake_minimum_required(VERSION 3.23)

option(REFLECTCPP_BUILD_SHARED "Build shared library" ${BUILD_SHARED_LIBS})

option(REFLECTCPP_BSON "Enable BSON support" OFF)
option(REFLECTCPP_CBOR "Enable CBOR support" OFF)
option(REFLECTCPP_FLEXBUFFERS "Enable flexbuffers support" OFF)
Expand All @@ -9,10 +10,11 @@ option(REFLECTCPP_XML "Enable XML support" OFF)
option(REFLECTCPP_TOML "Enable TOML support" OFF)
option(REFLECTCPP_YAML "Enable YAML support" OFF)

option(REFLECTCPP_BUILD_BENCHMARKS "Build benchmarks" OFF)
option(REFLECTCPP_BUILD_TESTS "Build tests" OFF)

set(REFLECTCPP_USE_VCPKG_DEFAULT OFF)
if (REFLECTCPP_BUILD_TESTS OR REFLECTCPP_BSON OR REFLECTCPP_CBOR OR REFLECTCPP_FLEXBUFFERS OR REFLECTCPP_MSGPACK OR REFLECTCPP_XML OR REFLECTCPP_TOML OR REFLECTCPP_YAML)
if (REFLECTCPP_BUILD_TESTS OR REFLECTCPP_BUILD_BENCHMARKS OR REFLECTCPP_BSON OR REFLECTCPP_CBOR OR REFLECTCPP_FLEXBUFFERS OR REFLECTCPP_MSGPACK OR REFLECTCPP_XML OR REFLECTCPP_TOML OR REFLECTCPP_YAML)
# enable vcpkg per default if require features other than JSON
set(REFLECTCPP_USE_VCPKG_DEFAULT ON)
endif()
Expand Down Expand Up @@ -93,6 +95,12 @@ if (REFLECTCPP_BUILD_TESTS)
add_subdirectory(tests)
endif ()

if (REFLECTCPP_BUILD_BENCHMARKS)
find_package(benchmark CONFIG REQUIRED)
target_link_libraries(reflectcpp INTERFACE benchmark::benchmark)
add_subdirectory(benchmarks)
endif ()

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

Expand Down
9 changes: 9 additions & 0 deletions benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O2")

if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std:c++20")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -Wall -Wno-sign-compare -Wno-missing-braces -Wno-psabi -pthread -fno-strict-aliasing -fwrapv -O2 -ftemplate-backtrace-limit=0 -fsanitize=undefined")
endif()

add_subdirectory(json)
16 changes: 16 additions & 0 deletions benchmarks/json/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
project(reflect-cpp-json-benchmarks)

file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.cpp")

add_executable(
reflect-cpp-json-benchmarks
${SOURCES}
)

target_include_directories(reflect-cpp-json-benchmarks SYSTEM PRIVATE "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include")

target_link_libraries(
reflect-cpp-json-benchmarks
PRIVATE
reflectcpp
)
137 changes: 137 additions & 0 deletions benchmarks/json/simple_read.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#include <benchmark/benchmark.h>

#include <iostream>
#include <rfl/json.hpp>

namespace simple_read {

static const std::string json_string = R"(
{
"first_name": "Homer",
"last_name": "Simpson",
"age": 45
}
)";

struct Person {
std::string first_name;
std::string last_name;
int age;
};

static void read_using_yyjson_naive() {
yyjson_doc *doc = yyjson_read(json_string.c_str(), json_string.size(), 0);
if (!doc) {
std::cout << "Could not parse document!" << std::endl;
return;
}
yyjson_val *root = yyjson_doc_get_root(doc);
yyjson_val *v;

Person homer;

v = yyjson_obj_get(root, "first_name");
if (v == NULL) {
std::cout << "'first_name' not found." << std::endl;
yyjson_doc_free(doc);
return;
}
auto first_name = yyjson_get_str(v);
if (first_name == NULL) {
std::cout << "Could not cast to string." << std::endl;
yyjson_doc_free(doc);
return;
}
homer.first_name = first_name;

v = yyjson_obj_get(root, "last_name");
if (v == NULL) {
std::cout << "'last_name' not found." << std::endl;
yyjson_doc_free(doc);
return;
}
auto last_name = yyjson_get_str(v);
if (last_name == NULL) {
std::cout << "Could not cast to string." << std::endl;
yyjson_doc_free(doc);
return;
}
homer.last_name = last_name;

v = yyjson_obj_get(root, "age");
if (v == NULL) {
std::cout << "'age' not found." << std::endl;
yyjson_doc_free(doc);
return;
}
if (!yyjson_is_int(v)) {
std::cout << "Could not cast to int." << std::endl;
yyjson_doc_free(doc);
return;
}
homer.age = yyjson_get_int(v);

yyjson_doc_free(doc);
}

static void read_using_yyjson_iter() {
yyjson_doc *doc = yyjson_read(json_string.c_str(), json_string.size(), 0);
if (!doc) {
std::cout << "Could not parse document!" << std::endl;
return;
}
yyjson_val *root = yyjson_doc_get_root(doc);

Person homer;

std::vector<std::string> errors;

yyjson_obj_iter iter;
yyjson_obj_iter_init(root, &iter);
yyjson_val *key;
while ((key = yyjson_obj_iter_next(&iter))) {
const auto name = std::string_view(yyjson_get_str(key));
const auto v = yyjson_obj_iter_get_val(key);
if (name == "first_name") {
auto first_name = yyjson_get_str(v);
if (first_name == NULL) {
errors.push_back(
"Error reading 'first_name': Could not cast to string.");
}
homer.first_name = first_name;
} else if (name == "last_name") {
auto last_name = yyjson_get_str(v);
if (last_name == NULL) {
errors.push_back(
"Error reading 'last_name': Could not cast to string.");
}
homer.last_name = last_name;
} else if (name == "age") {
if (!yyjson_is_int(v)) {
errors.push_back("Error reading 'age': Could not cast to int.");
}
homer.age = yyjson_get_int(v);
}
}

yyjson_doc_free(doc);
}

static void BM_simple_read_yyjson_naive(benchmark::State &state) {
for (auto _ : state) read_using_yyjson_naive();
}
BENCHMARK(BM_simple_read_yyjson_naive);

static void BM_simple_read_yyjson_iter(benchmark::State &state) {
for (auto _ : state) read_using_yyjson_iter();
}
BENCHMARK(BM_simple_read_yyjson_iter);

static void BM_simple_read_reflect_cpp(benchmark::State &state) {
for (auto _ : state) rfl::json::read<Person>(json_string);
}
BENCHMARK(BM_simple_read_reflect_cpp);

} // namespace simple_read

BENCHMARK_MAIN();
4 changes: 4 additions & 0 deletions vcpkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
"name": "yaml-cpp",
"version>=": "0.8.0#1"
},
{
"name": "benchmark",
"version>=": "1.8.3"
},
{
"name": "gtest",
"version>=": "1.14.0"
Expand Down

0 comments on commit add67da

Please sign in to comment.