Skip to content

build(json): migrate nlohmann/json → Glaze v7.6.0 (~9-15x parse speedup)#7

Merged
Reddimus merged 1 commit into
mainfrom
feat/glaze-migration
May 12, 2026
Merged

build(json): migrate nlohmann/json → Glaze v7.6.0 (~9-15x parse speedup)#7
Reddimus merged 1 commit into
mainfrom
feat/glaze-migration

Conversation

@Reddimus
Copy link
Copy Markdown
Owner

Summary

  • Replace nlohmann/json v3.11.3 with Glaze v7.6.0
  • 11 model headers, 10 model .cpp files migrated
  • New internal common_glaze_detail.hpp + pagination_detail.hpp (templated glz::meta<CDOResponseEnvelope<T>>)
  • Multi-format error parser (from_response) ported to glz::generic dispatch
  • Public CDOClient/DataServiceClient API unchanged
  • nlohmann FetchContent fully removed; 166/166 tests pass

Benchmark

x86_64-v3, GCC 13.3, -O3 -DNDEBUG, 21 KB CDO /stations?limit=100 envelope, 1k iters:

  • nlohmann v3.11.3: ~360-590 us/op
  • glaze v7.6.0: ~29-40 us/op
  • Speedup: 9-15x

glz::generic fallbacks

  • DataPoint / DataPointCollection — user-driven TMAX/TMIN/PRCP/SNOW columns sit as siblings to fixed DATE/STATION keys, no static glz::meta possible. Tagged TODO(glaze):.
  • core/error.cpp::from_response — 3 error shapes (CDO + Data Service + RFC 7807) dispatched via runtime branching.

Test plan

  • make format && make lint && cmake --build build && ctest --output-on-failure 166/166 pass
  • cpp_auto_audit clean

…dup)

Replaces the nlohmann/json v3.11.3 FetchContent dep with Glaze v7.6.0.
The public client surface (CDOClient::get_*, DataServiceClient::get_*,
parse_csv_data / parse_ssv_data) is unchanged; internal
`from_json(const nlohmann::json&, T&)` overloads and the transitional
`json_string` / `json_int` / `json_double` / `json_bool` helpers are
replaced with `deserialize_<T>(std::string_view, T&) -> Result<void>`
in the `ncei::` namespace.

Static-shape model structs (Dataset, DataCategory, DataType,
LocationCategory, Location, CDOStation, DataRecord, DatasetField,
DatasetMetadata, DataSearchResult, DatasetSearchResult) get
`glz::meta` specializations in their per-model `.cpp` files. The CDO
list-response envelope (`{metadata: {resultset: {...}}, results:
[...]}`) is parsed via a single templated meta in the internal-only
`src/models/pagination_detail.hpp` — every endpoint shares it. The
DataPoint family (user-driven TMAX/TMIN/PRCP columns -> attribute
pairs) uses `glz::generic` AST walking and is flagged with
`TODO(glaze):` markers.

`ncei::detail::kReadOpts` carries the CDO-friendly opts combo
(`error_on_unknown_keys = false` + `skip_null_members_on_read = true`)
since Glaze v7.6.0's `glz::opts` doesn't ship `skip_null_members_on_read`
as a base-struct member.

Benchmark (x86_64-v3, GCC 13.3, -O3 -DNDEBUG, 21 KB CDO stations
envelope, 1k iters):
- nlohmann/json v3.11.3 : ~360-590 us/op (pre-migration baseline)
- glaze v7.6.0          :  ~32-40  us/op (post-migration)
- speedup               :   9-15x

Removed `src/core/pagination.cpp` (its `from_json(ResultSetMetadata)`
overload is now redundant — the templated envelope meta handles it).
Added `tests/glaze_test.cpp` (parse-shape parity) and
`tests/parse_benchmark.cpp` (200 us/op regression cap, 30s ctest
timeout).
@Reddimus Reddimus merged commit 81ed5f6 into main May 12, 2026
4 checks passed
@Reddimus Reddimus deleted the feat/glaze-migration branch May 12, 2026 03:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant