Commit Graph
2 Commits
Author SHA1 Message Date
Niels Lohmann 64a5d233d0 json_view: from_json() of the macros reads views directly
get<T>() and get_to() of a view call T's from_json() with the view itself
when that from_json() accepts views but not an unrelated probe type, and
fall back to materialize() otherwise. The from_json() functions of the
NLOHMANN_DEFINE_TYPE_*, NLOHMANN_DEFINE_DERIVED_TYPE_* and
NLOHMANN_JSON_SERIALIZE_ENUM(_STRICT) macros accept basic_json values and
views; a derived type whose base reads only json reads the base part
through materialize(). The library's own from_json() overloads are not
called with views: from_json() of a view (and of the probe) only looks up
functions by ADL.

New public trait nlohmann::is_json_view<T>, and the member type
basic_json_type of basic_json_view. With duplicate keys, the members of
such a T are those the view's lookups find (the first ones).

bench_decode.cpp measures decoding into structs (4-6x faster than
materialize().get<T>() on twitter, citm_catalog, and synthetic records).

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-25 13:33:39 +01:00
Niels Lohmann 2dc1e54856 Compare json_view with yyjson, simdjson, and Boost.JSON (#5627)
* Compare json_view with yyjson, simdjson, and Boost.JSON

tests/benchmarks/json_view/ holds a comparison with other
libraries, answering the question users ask when they pick one.
It is not built by CMake and not run by CI.

- bench_view.cpp: parse, traverse, select and dump of twitter,
  citm_catalog, canada, jeopardy, a tweet and an RPC request,
  against json_view, yyjson, simdjson, Boost.JSON and json::parse,
  all agreeing and run interleaved.
- bench_corpus.cpp: parse, traverse and dump of any file list.
- bench_edit.cpp: parses, edits through each library's own API,
  and serializes; all outputs must describe the same value.
- compare.py: builds both programs with system or pinned,
  SHA-256-checked downloads, and writes results with the commit,
  CPU, OS, compiler and library versions.
- README.md and a workflow that runs on demand or via a PR label.

Fairness fixes folded in: each engine runs once untimed before
each timed round, so the next one no longer pays for the
previous one's cleanup; dump is also compared with source numbers
against yyjson's raw-number mode; a "simdjson DOM (fresh)" column
and a reused-document column for json_view were added;
compare.py's paths are absolute; downloads use a .part file and a
failed checksum removes the archive.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Make the downloads of json_view's compare.py robust

Hash the archives in chunks instead of reading them into memory, download
with a timeout, extract into a temporary directory that is renamed into
place only after success (a half-extracted directory was trusted forever),
and split CXX and CC into arguments so that values like 'ccache g++' work.
Note at the pins that a SHA-256 mismatch of a GitHub tag archive means
that GitHub regenerated it.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Add a timeout and a concurrency group to the json_view benchmarks

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Check the CSV file and the round count in the json_view benchmarks

fopen() of the CSV output was not checked, so an unwritable directory made
fprintf() write to a null FILE*; the round count is parsed with strtol and
clamped instead of atoi.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-22 08:40:33 +02:00