Skip to content

Optimize numeric vectors in Cereal, YAS, and Boost binary - #740

Merged
liuzicheng1987 merged 1 commit into
getml:mainfrom
Altren:perf/bulk-numeric-vectors
Oct 16, 2026
Merged

liuzicheng1987 merged 1 commit into
getml:mainfrom
Altren:perf/bulk-numeric-vectors

Conversation

@Altren

@Altren Altren commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Cereal, YAS, and Boost.Serialization binary currently serialize numeric vectors one element at a time. Transfer their contiguous numeric payloads in one archive operation while preserving the adapters’ existing array lengths and parent metadata.

  • Cereal retains the size_t length prefix and uses typed binary_data, including per-element byte swapping for portable archives.
  • YAS retains the size_t prefix and uses block I/O for its existing uncompressed host-endian binary archive.
  • Boost specializes only binary_iarchive / binary_oarchive, retaining the uint64_t length prefix and using load_binary / save_binary. Other archive types keep the generic parser.
  • vector<bool>, Vectorstring, and non-arithmetic element types keep their existing paths. Schema generation remains inherited from VectorParser.

Validation:

  • Four additional numeric-vector tests pass with CEREAL_SIZE_TYPE=uint32_t.
  • New shared tests compare bytes against the original element-by-element parser and read in both directions. They cover integer widths/signs, float/double, empty vectors, boundaries, negative zero, infinities/NaNs, nested arrays, maps, optional/variant values, NoFieldNames, truncated payloads, and excessive lengths.
  • Cereal tests exercise both little- and big-endian output. Boost tests verify the text-archive fallback.
  • All three large numeric-vector fixtures have identical before/after bytes and successfully read baseline output. All 60 corresponding benchmark case runs complete successfully.

Added bulk_numeric_vectors to the existing all-format benchmark executable and Linux/macOS/Windows benchmark summaries. The results below cover a deterministic std::vector<uint64_t> with 1.5 million elements, using ordinary reflect-cpp APIs without custom serializers or field annotations.

To isolate the incremental benefit, both measured variants include #738 and the reserve-capacity changes from #739 (ce5db49). The optimized variant adds only this PR’s bulk-I/O changes. This branch itself is based on upstream main and does not depend on #739.

Format Dataset Operation Before (ms) After (ms) Speedup Serialized bytes
Cereal 1.5M IDs write 5.789 0.391 14.81× 12,000,009
Cereal 1.5M IDs read 10.377 0.379 27.37× 12,000,009
YAS 1.5M IDs write 1.440 0.585 2.46× 12,000,015
YAS 1.5M IDs read 7.109 0.205 34.75× 12,000,015
Boost binary 1.5M IDs write 5.136 0.396 12.98× 12,000,008
Boost binary 1.5M IDs read 9.882 0.388 25.45× 12,000,008

Run the benchmark:

./build/benchmarks/all/reflect-cpp-all-format-benchmarks \
  --benchmark_filter='bulk_numeric_vectors/[^/]+/ids/' \
  --benchmark_min_warmup_time=0.1 \
  --benchmark_min_time=0.2s \
  --benchmark_repetitions=5

Preserve each adapter's array length and parent metadata while transferring numeric vector payloads in bulk. Keep Cereal portable byte swapping and restrict Boost optimization to standard binary archives.

Add wire-compatibility and error-path regression tests, plus deterministic numeric-vector and World benchmarks for all three formats. Validated 141 format tests, four focused Cereal size-type tests, and 180 benchmark case runs.
@liuzicheng1987

Copy link
Copy Markdown
Collaborator

That's a great contribution. Thanks!

@liuzicheng1987
liuzicheng1987 merged commit 4cf550b into getml:main Oct 16, 2026
176 checks passed
@Altren
Altren deleted the perf/bulk-numeric-vectors branch October 17, 2026 08:43
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.

2 participants