Skip to content

Commit

Permalink
Adding Jsonifier parsing/serializing library.
Browse files Browse the repository at this point in the history
  • Loading branch information
RealTimeChris committed Apr 26, 2024
1 parent 814128a commit 677a413
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 2 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@
.vscode/
.cache/
compile_commands.json
.DS_Store
.DS_Store
.vs/
out/
9 changes: 8 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(glaze)

FetchContent_Declare(
Jsonifier
GIT_REPOSITORY https://github.com/RealTimeChris/Jsonifier.git
GIT_TAG dev
)
FetchContent_MakeAvailable(Jsonifier)

FetchContent_Declare(
rapidjson
URL https://github.com/Tencent/rapidjson/archive/refs/tags/v1.1.0.tar.gz
Expand Down Expand Up @@ -101,7 +108,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE include ${json_struct_SOURCE_

find_package(Qt5 COMPONENTS Core)

target_link_libraries(${PROJECT_NAME} PRIVATE nlohmann_json::nlohmann_json glaze::glaze daw::daw-json-link simdjson yyjson fmt::fmt Boost::json)
target_link_libraries(${PROJECT_NAME} PRIVATE nlohmann_json::nlohmann_json glaze::glaze daw::daw-json-link simdjson yyjson fmt::fmt Boost::json Jsonifier::Jsonifier)

if (Qt5_FOUND)
target_compile_definitions(${PROJECT_NAME} PRIVATE HAVE_QT=1)
Expand Down
172 changes: 172 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ static constexpr std::string_view json0 = R"(
#include <iostream>
#include <unordered_map>

#include <jsonifier/Index.hpp>
#include "fmt/format.h"
#include "boost/describe/class.hpp"

Expand Down Expand Up @@ -153,6 +154,64 @@ struct glz::meta<obj_t> {
);
};

template <>
struct jsonifier::core<fixed_object_t> {
using T = fixed_object_t;
static constexpr auto parseValue = createValue<
&T::int_array,
&T::float_array,
&T::double_array
>();
};

template <>
struct jsonifier::core<fixed_name_object_t> {
using T = fixed_name_object_t;
static constexpr auto parseValue = createValue<
&T::name0,
&T::name1,
&T::name2,
&T::name3,
&T::name4
>();
};

template <>
struct jsonifier::core<nested_object_t> {
using T = nested_object_t;
static constexpr auto parseValue = createValue<
&T::v3s,
&T::id
>();
};

template <>
struct jsonifier::core<another_object_t> {
using T = another_object_t;
static constexpr auto parseValue = createValue<
&T::string,
&T::another_string,
&T::escaped_text,
&T::boolean,
&T::nested_object
>();
};

template <>
struct jsonifier::core<obj_t> {
using T = obj_t;
static constexpr auto parseValue = createValue<
&T::fixed_object,
&T::fixed_name_object,
&T::another_object,
&T::string_array,
&T::string,
&T::number,
&T::boolean,
&T::another_bool
>();
};

// for testing large, flat documents and out of sequence reading
template <bool backward>
struct abc_t
Expand Down Expand Up @@ -195,6 +254,22 @@ struct glz::meta<abc_t<true>>
&T::m,&T::l,&T::k,&T::j,&T::i,&T::h,&T::g,&T::f,&T::e,&T::d,&T::c,&T::b,&T::a);
};

template <>
struct jsonifier::core<abc_t<false>>
{
using T = abc_t<false>;
static constexpr auto parseValue = createValue<&T::a, &T::b, &T::c, &T::d, &T::e, &T::f, &T::g, &T::h, &T::i, &T::j, &T::k, &T::l, &T::m, &T::n,
&T::o, &T::p, &T::q, &T::r, &T::s, &T::t, &T::u, &T::v, &T::w, &T::x, &T::y, &T::z>();
};

template <>
struct jsonifier::core<abc_t<true>>
{
using T = abc_t<true>;
static constexpr auto parseValue = createValue<&T::z, &T::y, &T::x, &T::w, &T::v, &T::u, &T::t, &T::s, &T::r, &T::q, &T::p, &T::o, &T::n,
&T::m, &T::l, &T::k, &T::j, &T::i, &T::h, &T::g, &T::f, &T::e, &T::d, &T::c, &T::b, &T::a>();
};

#ifdef NDEBUG
static constexpr size_t iterations = 1'000'000;
static constexpr size_t iterations_abc = 10'000;
Expand Down Expand Up @@ -483,6 +558,101 @@ auto glaze_abc_test()
return r;
}

auto jsonifier_test()
{
jsonifier::jsonifier_core parser{};
std::string buffer{ json0 };

obj_t obj;

auto t0 = std::chrono::steady_clock::now();

try {
for (size_t i = 0; i < iterations; ++i) {
parser.parseJson(obj, buffer);
parser.serializeJson(obj, buffer);
}
}
catch (const std::exception& e) {
std::cout << "jsonifier error: " << e.what() << '\n';
}

auto t1 = std::chrono::steady_clock::now();

for (auto& value : parser.getErrors()) {
std::cout << "Jsonifier Error: " << value.reportError() << std::endl;
}

results r{ "jsonifier", "https://github.com/realtimechris/jsonifier", iterations };
r.json_roundtrip = std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count() * 1e-6;

// write performance
t0 = std::chrono::steady_clock::now();

for (size_t i = 0; i < iterations; ++i) {
parser.serializeJson(obj, buffer);
}

t1 = std::chrono::steady_clock::now();

r.json_byte_length = buffer.size();
minified_byte_length = *r.json_byte_length;
r.json_write = std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count() * 1e-6;

is_valid_write<obj_t>(buffer, "jsonifier");
// read performance

t0 = std::chrono::steady_clock::now();

for (size_t i = 0; i < iterations; ++i) {
parser.parseJson<true>(obj, buffer);
}

t1 = std::chrono::steady_clock::now();

for (auto& value : parser.getErrors()) {
std::cout << "Jsonifier Error: " << value.reportError() << std::endl;
}

r.json_read = std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count() * 1e-6;

r.print();

return r;
}

auto jsonifier_abc_test()
{
std::string buffer{};

results r{ "jsonifier", "https://github.com/RealTimeChris/Jsonifier", iterations_abc };

jsonifier::jsonifier_core parser{};
parser.serializeJson(abc_t<true>{}, buffer);
// read performance

abc_t<false> obj{};

auto t0 = std::chrono::steady_clock::now();

for (size_t i = 0; i < iterations_abc; ++i) {
parser.parseJson<true>(obj, buffer);
}

auto t1 = std::chrono::steady_clock::now();

for (auto& value : parser.getErrors()) {
std::cout << "Jsonifier Error: " << value.reportError() << std::endl;
}

r.json_byte_length = buffer.size();
r.json_read = std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count() * 1e-6;

r.print(false);

return r;
}

#include <daw/json/daw_json_link.h>

template<>
Expand Down Expand Up @@ -1899,6 +2069,7 @@ void test0()
std::vector<results> results;
results.emplace_back(glaze_test());
results.emplace_back(simdjson_test());
results.emplace_back(jsonifier_test());
results.emplace_back(yyjson_test());
results.emplace_back(daw_json_link_test());
results.emplace_back(rapidjson_test());
Expand Down Expand Up @@ -1927,6 +2098,7 @@ void abc_test()
{
std::vector<results> results;
results.emplace_back(glaze_abc_test());
results.emplace_back(jsonifier_abc_test());
//results.emplace_back(daw_json_link_abc_test());
results.emplace_back(simdjson_abc_test());

Expand Down

0 comments on commit 677a413

Please sign in to comment.