Repository navigation
Comparison to Glaze #1102
Description
Activity
I actually experimented with it, but then dropped it for some reason I already forgot.
Local results
Parse /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,boost (direct),363 Parse /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,boost (pool),369 Parse /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,glaze,1381 Parse /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,boost (direct),496 Parse /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,boost (pool),353 Parse /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,glaze,825 Parse /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,boost (direct),640 Parse /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,boost (pool),788 Parse /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,glaze,1880 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,boost (direct),1567 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,boost (pool),307 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,glaze,4908 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,boost (direct),491 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,boost (pool),209 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,glaze,610 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,boost (direct),2275 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,boost (pool),539 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,glaze,8275Note that I haven't checked that Glaze produces correct outputs yet.
does glaze have a DOM?
Kinda. Their value type is a wrapper over
std::variantofstd::nullpr_t, bool, double,std::vector, andstd::map. I'm adding it to the benchmark too.Local results
Parse /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,boost (direct),363 Parse /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,boost (pool),369 Parse /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,glaze,1381 Parse /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,boost (direct),496 Parse /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,boost (pool),353 Parse /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,glaze,825 Parse /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,boost (direct),640 Parse /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,boost (pool),788 Parse /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,glaze,1880 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,boost (direct),1567 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,boost (pool),307 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,glaze,4908 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,boost (direct),491 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,boost (pool),209 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,glaze,610 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,boost (direct),2275 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,boost (pool),539 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,glaze,8275Note that I haven't checked that Glaze produces correct outputs yet.
@grisumbras what the numbers mean?
I recently saw a mention of the Glaze library, looked at their benchmark and to be honest its worst benchmark i've seen in a while.
Their benchmark looks so fake that I'm curious about the real numbers.
On the other hand, I know an implementation on top of the Boost Json that does direct stream parsing into values and beats the native Boost Json implementation, maybe later I'll give you the code to add to the benchmark
@grisumbras what the numbers mean?
Megabytes per second.
boost (direct)is using Boost.JSON with direct operations.boost (pool)is using Boost.JSON with DOM,monotonic_resource, andvalue_to/from.Glaze is indeed very fast when you use it with direct operations (how it was intended to be used).
On the other hand, I know an implementation on top of the Boost Json that does direct stream parsing into values and beats the native Boost Json implementation, maybe later I'll give you the code to add to the benchmark
Can you give a link? If it doesn't break
parse_intoAPI, I may integrate it into the library myself.Now, these are the benchmarks for JSON DOM and Glaze "DOM" (
glz::json_t).Parse /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,boost,425 Parse /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,boost (pool),596 Parse /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,glaze,275 Parse /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,boost,356 Parse /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,boost (pool),547 Parse /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,glaze,229 Parse /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,boost,543 Parse /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,boost (pool),1177 Parse /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,glaze,328 Parse /home/grisumbras/dev/boost/libs/json/bench/data/github_events.json,gcc x64/sse2,boost,375 Parse /home/grisumbras/dev/boost/libs/json/bench/data/github_events.json,gcc x64/sse2,boost (pool),825 Parse /home/grisumbras/dev/boost/libs/json/bench/data/github_events.json,gcc x64/sse2,glaze,254 Parse /home/grisumbras/dev/boost/libs/json/bench/data/gsoc-2018.json,gcc x64/sse2,boost,831 Parse /home/grisumbras/dev/boost/libs/json/bench/data/gsoc-2018.json,gcc x64/sse2,boost (pool),1814 Parse /home/grisumbras/dev/boost/libs/json/bench/data/gsoc-2018.json,gcc x64/sse2,glaze,591 Parse /home/grisumbras/dev/boost/libs/json/bench/data/instruments.json,gcc x64/sse2,boost,308 Parse /home/grisumbras/dev/boost/libs/json/bench/data/instruments.json,gcc x64/sse2,boost (pool),654 Parse /home/grisumbras/dev/boost/libs/json/bench/data/instruments.json,gcc x64/sse2,glaze,215 Parse /home/grisumbras/dev/boost/libs/json/bench/data/marine_ik.json,gcc x64/sse2,boost,289 Parse /home/grisumbras/dev/boost/libs/json/bench/data/marine_ik.json,gcc x64/sse2,boost (pool),534 Parse /home/grisumbras/dev/boost/libs/json/bench/data/marine_ik.json,gcc x64/sse2,glaze,120 Parse /home/grisumbras/dev/boost/libs/json/bench/data/mesh.json,gcc x64/sse2,boost,459 Parse /home/grisumbras/dev/boost/libs/json/bench/data/mesh.json,gcc x64/sse2,boost (pool),580 Parse /home/grisumbras/dev/boost/libs/json/bench/data/mesh.json,gcc x64/sse2,glaze,214 Parse /home/grisumbras/dev/boost/libs/json/bench/data/mesh.pretty.json,gcc x64/sse2,boost,911 Parse /home/grisumbras/dev/boost/libs/json/bench/data/mesh.pretty.json,gcc x64/sse2,boost (pool),1106 Parse /home/grisumbras/dev/boost/libs/json/bench/data/mesh.pretty.json,gcc x64/sse2,glaze,425 Parse /home/grisumbras/dev/boost/libs/json/bench/data/numbers.json,gcc x64/sse2,boost,791 Parse /home/grisumbras/dev/boost/libs/json/bench/data/numbers.json,gcc x64/sse2,boost (pool),877 Parse /home/grisumbras/dev/boost/libs/json/bench/data/numbers.json,gcc x64/sse2,glaze,446 Parse /home/grisumbras/dev/boost/libs/json/bench/data/random.json,gcc x64/sse2,boost,223 Parse /home/grisumbras/dev/boost/libs/json/bench/data/random.json,gcc x64/sse2,boost (pool),347 Parse /home/grisumbras/dev/boost/libs/json/bench/data/random.json,gcc x64/sse2,glaze,134 Parse /home/grisumbras/dev/boost/libs/json/bench/data/twitter.json,gcc x64/sse2,boost,317 Parse /home/grisumbras/dev/boost/libs/json/bench/data/twitter.json,gcc x64/sse2,boost (pool),526 Parse /home/grisumbras/dev/boost/libs/json/bench/data/twitter.json,gcc x64/sse2,glaze,212 Parse /home/grisumbras/dev/boost/libs/json/bench/data/twitterescaped.json,gcc x64/sse2,boost,278 Parse /home/grisumbras/dev/boost/libs/json/bench/data/twitterescaped.json,gcc x64/sse2,boost (pool),461 Parse /home/grisumbras/dev/boost/libs/json/bench/data/twitterescaped.json,gcc x64/sse2,glaze,186 Parse /home/grisumbras/dev/boost/libs/json/bench/data/update-center.json,gcc x64/sse2,boost,322 Parse /home/grisumbras/dev/boost/libs/json/bench/data/update-center.json,gcc x64/sse2,boost (pool),555 Parse /home/grisumbras/dev/boost/libs/json/bench/data/update-center.json,gcc x64/sse2,glaze,167 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,boost,1635 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,boost (pool),1667 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/apache_builds.json,gcc x64/sse2,glaze,1524 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,boost,548 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,boost (pool),550 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/canada.json,gcc x64/sse2,glaze,510 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,boost,1990 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,boost (pool),2093 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/citm_catalog.json,gcc x64/sse2,glaze,1432 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/github_events.json,gcc x64/sse2,boost,1697 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/github_events.json,gcc x64/sse2,boost (pool),1705 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/github_events.json,gcc x64/sse2,glaze,1893 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/gsoc-2018.json,gcc x64/sse2,boost,1503 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/gsoc-2018.json,gcc x64/sse2,boost (pool),1547 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/gsoc-2018.json,gcc x64/sse2,glaze,1886 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/instruments.json,gcc x64/sse2,boost,1391 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/instruments.json,gcc x64/sse2,boost (pool),1411 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/instruments.json,gcc x64/sse2,glaze,1263 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/marine_ik.json,gcc x64/sse2,boost,461 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/marine_ik.json,gcc x64/sse2,boost (pool),481 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/marine_ik.json,gcc x64/sse2,glaze,305 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/mesh.json,gcc x64/sse2,boost,413 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/mesh.json,gcc x64/sse2,boost (pool),413 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/mesh.json,gcc x64/sse2,glaze,371 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/mesh.pretty.json,gcc x64/sse2,boost,880 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/mesh.pretty.json,gcc x64/sse2,boost (pool),887 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/mesh.pretty.json,gcc x64/sse2,glaze,807 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/numbers.json,gcc x64/sse2,boost,427 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/numbers.json,gcc x64/sse2,boost (pool),426 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/numbers.json,gcc x64/sse2,glaze,514 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/random.json,gcc x64/sse2,boost,880 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/random.json,gcc x64/sse2,boost (pool),938 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/random.json,gcc x64/sse2,glaze,516 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/twitter.json,gcc x64/sse2,boost,1598 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/twitter.json,gcc x64/sse2,boost (pool),1619 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/twitter.json,gcc x64/sse2,glaze,1369 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/twitterescaped.json,gcc x64/sse2,boost,1423 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/twitterescaped.json,gcc x64/sse2,boost (pool),1450 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/twitterescaped.json,gcc x64/sse2,glaze,1204 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/update-center.json,gcc x64/sse2,boost,1040 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/update-center.json,gcc x64/sse2,boost (pool),1086 Serialize /home/grisumbras/dev/boost/libs/json/bench/data/update-center.json,gcc x64/sse2,glaze,727In this case Glaze parses much slower than Boost.JSON using the default memory resource (which is in turn much slower than when
monotonic_reqourceis used). Difference in serialization speed is less pronounced. Glaze even outperforms Boost.JSON onnumbers.json(that file is a giant array of numbers). This is due to it directly using Dragnobox. I'm considering doing the same for Boost.JSON.The most obvious conclusion is that Boost.JSON is absolutely superior if you need a DOM. If you can avoid a DOM, Glaze will probably always be faster. There are still other benefits Boost.JSON has, like actual documentation and streaming I/O support.
Can you give a link? If it doesn't break parse_into API, I may integrate it into the library myself.
First of all, i see you use only gcc in your benchmark, it may be useful to add clang into comparison. On my benchmark, there are cases when gcc 5 times worse than clang
About different solution for direct parsing - it uses parse api from Boost Json, key idea to use recusrive generator coroutine for implementing parsing for all types
So, there are stream_parser:
struct stream_parser { boost::json::basic_parser<boostjson_sax_producer> p; template <typename T> explicit stream_parser(T& t, std::span<byte_t> buf = {}); void feed(std::string_view data, bool end, io_error_code& ec) { p.write_some(!end, data.data(), data.size(), ec); ... } };
and
boostjson_sax_producerhere implemented on top of recursive generatorThen, parsing for concrete type implemented as coroutine, e.g. for vector of T:
generator_type parse(std::vector<T>& v, sax_token& tok, dd::with_stack_resource r) { tok.expect(sax_token::array_begin); for (;;) { co_yield {}; if (tok.got == sax_token::array_end) break; co_yield dd::elements_of(parser_for<T>(v.emplace_back(), tok, r)); } }
I did run benchmarks with Clang too. The results are in the same ballpark. Interestingly, Clang is consistently slower for most benchmarks for me (but not by much).
About different solution for direct parsing - it uses parse api from Boost Json, key idea to use recusrive generator coroutine for implementing parsing for all types
This is very interesting. I obviosuly cannot make it the default implementation in a C++11 library, but this can be a great example in the docs or even an alternative implementation.
We need to evaluate the performance of Boost.JSON against Glaze. Pure DOM (
json::value) and to/from struct (apples to apples).