perf(mojo): vendor one-pass float, 4-digit SWAR, and ctz scan - #1
Closed
leo-gan wants to merge 67 commits into
Closed
perf(mojo): vendor one-pass float, 4-digit SWAR, and ctz scan#1leo-gan wants to merge 67 commits into
leo-gan wants to merge 67 commits into
Conversation
I didn't test it out, so expect minor systax issues. Basically - honor zero-copy - reuse encoder/decoder for io-based flow also This should give more expected results. Thanks.
* docs(theory): first pass toward student-friendly course prose Expand definitions and transitions across Serialization 101–401 so first-year readers can follow jargon. Links, diagrams, and technical meaning preserved. Further sentence-level rewrites still needed for dense original passages. * docs(theory): rewrite course prose sentence-by-sentence for first-year readers Rewrite Serialization 101–401 articles into clear textbook English. Split dense multi-clause sentences, define technical terms in plain language, and replace remaining industry jargon without changing meaning. Preserve links, diagrams, code samples, and technical claims. * chore: add clean-logs skill and prune available_runs to latest stems Add a /clean-logs skill and script that keep only the latest run stem per language. Refresh available_runs.json to match the pruned set so the dashboard run picker stays consistent. * docs: promote Dashboard to top-level MkDocs tab Restructure site nav to Dashboard | Learn | Languages | Method so the interactive dashboard is a first-class tab instead of a nested item under Benchmarks. Point Method and theory cross-links at the new tabs. * feat(dashboard): shared site wordmark header, keep analytics chrome Replace the local “Serializer Analytics” header and “Back to Docs” escape hatch with the docs product wordmark and peer links (Dashboard · Learn · Languages · Method · GitHub). Section tabs are Overview · Details · Compare · History. Filter bar, meta panels, and analytics styling are unchanged. * docs(dashboard): add Proposal B header wordmark mock artifacts Keep the before/after HTML mock and screenshot used to approve the shared wordmark header design. * docs: add storefront landing page as site root Replace the root redirect to Serialization 101 with a home storefront that dual-CTAs into Dashboard and Learn, and links Languages and Method. Root URL is now the project front door (Proposal D). * docs: polish site nav, storefront, and language overview template Make language sidebar rows short and clickable (name · Results), sort languages alphabetically, and land the Languages tab on C. Refine the storefront (no Home title, Serializers table matching the menu), hide auto page titles when requested, and standardize each language overview to intro + Benchmark runner + sorted Serializers without suite-type sections. Dashboard site peers use a GitHub icon and link Languages to C. * feat(analysis): clarify Results sample filter and enrich summary tables Document the Dashboard Samples outlier policy (default IQR k=1.5) on language Results pages. Drop Fidelity and Samples-count columns from Summary, label Total Time columns in µs, and add an Ops/Sec Average column matching Dashboard all@all aggregation. Regenerate published results and violin plots. * chore: remove temporary dashboard mock assets Drop header-wordmark and languages-nav mock HTML/PNG used during design review; they are not part of the published site.
#78) * docs: role-oriented README and dashboard first-visit orientation Expand reader roles with know/want paths, add honesty rules for reading benchmark numbers, and surface a dismissible dashboard tip plus clearer data-type labels. Add the improve-docs skill with Roles/Research/Style. * docs: restore README to pre-role-oriented wording Revert the expanded Who it is for section and How to read the numbers block; keep the original audience table and honesty line under Statistics. * docs: deep storefront, language explore strips, dashboard workload story Validate site articles end-to-end: role path cards on home, jump tables on theory levels, Method reading order and count fixes, explore strips on all language overviews, and a clearer dashboard (primary filters, viewing strip, scatter axis help, empty states). Capture README prefs in improve-docs skill. * docs: drop redundant dashboard strip and language explore bars Remove the Viewing workload story (filters already show context), remove lang-explore strips from language overviews, and restore docs/index.md to the pre-storefront-rewrite layout.
Skip UTF-8 validation on decode for trusted generated fixtures (2–12% decode speedup). Comment cleanups from library author @fxamacker.
#83) Add an experiments/ notebook aimed at builders and researchers: a living plan, one experiment.yaml per study, a shared sample, and per-language runs. Experiment 1 asks which JSON library to keep for one nested document, reports similar/close groups instead of a single winner, and writes a combined results.md plus results.json a dashboard can reload from the saved CSVs.
* feat(experiments): add flat-record format comparison across nine languages Experiment 2 asks whether an internal service should leave JSON for MessagePack or Protocol Buffers on one small flat record (Sample B, N=1 and N=100). Results are grouped similar/close/slower per language; leaving JSON is language-specific on this sample. Teach implement-experiment to start with new-task and finish by opening a PR. * docs(experiments): link Experiment 2 pull request in the plan
…#85) * feat(experiments): compare one-language stores to portable formats Experiment 3 asks what we pay to stay readable by other languages on one flat record (Sample B). Python pickle/cloudpickle/dill, Java serialization/Kryo/Fory/Hessian, and Go gob are slower than a portable library on this sample. There is no speed gain here to trade for lock-in. * docs(experiments): link Experiment 3 pull request in the plan * chore(experiments): keep run logs local; commit results only Do not track experiment CSVs. Saved results.md and results.json are enough. Update implement-experiment so future labs do not add logs.
Keep results.md and results.json. Raw CSVs stay local. Teach implement-experiment not to commit experiment logs.
* feat(experiments): measure when JSON outgrows a sensor list Experiment 4 grows Sample C from 8 to 512 numbers and compares JSON, CBOR, MessagePack, postcard, and Protocol Buffers in Rust and C. Size is the first number. Trust the Rust curve: C sizes do not grow with the list. Expand experiment.yaml settings.points lists into one runner cell per length. * docs(experiments): link Experiment 4 pull request in the plan
Move JsonconsCbor/Msgpack/Bson into ser_jsoncons.cpp and encode domain structs with jsoncons member traits. The old path dumped through nlohmann JSON, which mixed two libraries on the timed call. BSON batches still wrap arrays because a BSON root must be a document. Fixes #82
* Add Experiment 12: is the difference the format, or the library? Hold one library still (Jackson, nlohmann, ugorji, Bond) and compare formats, then keep the format still and change the library. Ran Java, C++, Go, C#, and JavaScript on Sample A (full). Combined page is experiments/12-format-vs-library/results.md. * docs(experiments): link Experiment 12 PR #89 in the plan
* Add Experiment 13: do named-JSON ranks stay put? Same JSON libraries as Experiment 1, all nine languages, Samples A–E, 1 and 100 records, in memory. Also allow experiment.yaml sample.kind to be a list (needed by later labs that use more than one sample). * docs(experiments): link Experiment 13 PR #90 in the plan
Python, Java, and Go on Sample D at 1 and 100 records. Combined page is experiments/05-event-log-formats/results.md.
Java, JavaScript, Go, Rust, and C on Sample A. BSON loses a full write-and-read. Combined page: experiments/06-document-db-formats/results.md.
C++, C#, JavaScript, Python, and Rust on Sample A and Sample C (512 numbers). Combined page: experiments/07-write-once-read-many/results.md.
* Add Experiment 8: YAML, TOML, and XML versus JSON Go, Swift, and C# on Sample A and Sample E. YAML stays a file. Combined page: experiments/08-human-files/results.md. * Add Experiment 9: size after gzip or zstd Python only — other language runners do not record compressed size. Combined page: experiments/09-compression-size/results.md. * Add Experiments 10 and 11, plus the not-covered list Experiment 10: 1 vs 100 records (JSON / MessagePack / protobuf) on Samples B and D, all nine languages. Experiment 11: memory vs real stream on Sample A in Go, Java, and C++. PLAN.md now has a Not covered table: what we skipped, why, and how to fix it.
Order: C points (wrapper) then re-run Experiment 4; then experiment-only Avro/BSON/FlatBuffers rows; then gzip size columns; then small C-steps.
The C runner always built 32 sensor numbers and clamped the list at 64, so Experiment 4 could not answer the size curve. Read points (and the other type_config knobs) from the resolved cell and raise V2_MAX_POINTS to 512.
C sizes now grow with the sensor list and match the Rust curve. JSON 226→9371 bytes from 8 to 512 numbers.
…iment 5 (#98) C#, Rust, JavaScript, C, C++, and Swift now sit beside Python, Java, and Go on Sample D. Combined page lists similar/close sets per language.
Experiment 6: SwiftBSON vs JSON and MessagePack on Sample A. Experiment 7: C flatcc and Swift FlatBuffers/CapnProto vs protobuf.
One-shot gzip(6) of written bytes after the clock, matching the Python runner. zstd(3) is filled where an encoder is already available (Go, Rust, and C/C++/JS when libzstd or Node zstd is present). Java, C#, and Swift leave SizeZstd empty. The analysis parser already reads those columns. Experiment 9 is not re-run here (B4).
Default to archive.ubuntu.com and copy jammy debs from the repo root when the mirror 404s. After this script, CMake reports serializer: protobuf (libprotobuf) REAL via sysroot.
After the sysroot script (#102), CMake registers protobuf 3.12.4. On Sample A it writes the same 164 bytes as the in-tree wire helper. On 512 numbers it is smaller and faster than protobuf-wire.
Python/C# BSON need new harness clients. Sequential vs shuffle needs a runner flag and a full Experiment 13 re-run. Not small enough to finish cleanly in this pass.
…Sharp (#106) Research matched official libraries already used elsewhere in the suite: - Java FlatBuffers (flatbuffers-java + generated tables from benchmark.fbs) - Java Cap'n Proto (org.capnproto:runtime + generated BenchmarkCapnp) - YAML: PyYAML (already a dep), jackson-dataformat-yaml, js-yaml, serde_yaml, libyaml, yaml-cpp - C# MessagePack-CSharp with ContractlessStandardResolver - C yyjson native FILE* stream path (other C/Swift codecs stay copied) Experiment tables are not re-run here.
#107) Re-ran Experiment 7 (Java), Experiment 8 (six YAML languages), and Experiments 2 and 10 (C# MessagePack-CSharp). Logs stay local.
…reams (#108) Record correspondent libraries and the D1–D7 order. Do not start this work until a new task picks it up.
Keep the one-line run meta; add L1 badge and a Run configuration panel.
* dashboard: surface L1 run identity on Overview Keep the one-line run meta; add L1 badge and a Run configuration panel. * dashboard: show stream-honesty counts and Details column Add Mode chip and Honesty column (visible in stream mode). * fix: address review feedback for dashboard: show stream-honesty counts and Details column
* dashboard: surface L1 run identity on Overview Keep the one-line run meta; add L1 badge and a Run configuration panel. * dashboard: show stream-honesty counts and Details column Add Mode chip and Honesty column (visible in stream mode). * fix: address review feedback for dashboard: show stream-honesty counts and Details column * dashboard: canonicalize mode=bytes|stream; persist policy and ser= Alias C# string/Stream; add policy and ser query params.
* dashboard: surface L1 run identity on Overview Keep the one-line run meta; add L1 badge and a Run configuration panel. * dashboard: show stream-honesty counts and Details column Add Mode chip and Honesty column (visible in stream mode). * fix: address review feedback for dashboard: show stream-honesty counts and Details column * dashboard: canonicalize mode=bytes|stream; persist policy and ser= Alias C# string/Stream; add policy and ser query params. * analysis: write language reports under reports/, not docs/ Default unpublished markdown; violins opt-in; leave site Results pages alone.
…at Dashboard * dashboard: surface L1 run identity on Overview Keep the one-line run meta; add L1 badge and a Run configuration panel. * dashboard: show stream-honesty counts and Details column Add Mode chip and Honesty column (visible in stream mode). * fix: address review feedback for dashboard: show stream-honesty counts and Details column * dashboard: canonicalize mode=bytes|stream; persist policy and ser= Alias C# string/Stream; add policy and ser query params. * analysis: write language reports under reports/, not docs/ Default unpublished markdown; violins opt-in; leave site Results pages alone. * docs: move Rust fidelity/category rule to index; point all languages at Dashboard Add Numbers pointers; keep Results pages live.
* docs: unpublish language Results; Dashboard is the L1 artifact Delete results pages and violin PNGs; rewrite inbound links; inject Dashboard in Languages nav. * fix: address review feedback for docs: unpublish language Results
* Add missing forward declarations in bench.h Newer clang (Apple clang 21+) promotes implicit-function-declaration to an error under C11+. Declare bench_now_ns and bench_fidelity_cell in bench.h so run_v2.c can call them without the harness failing to build from a fresh clone. Definitions are unchanged (runner.c and batch_cell.c respectively). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * libcbor: streaming wrapper row, DOM tuning, native decoder Follow-up to the call-path / fairness review request at PJK/libcbor#433. Rework the libcbor row so libcbor is benchmarked with its own idiomatic APIs and no cross-library helper. Net published-benchmark impact: DOM encode ~1.7–2.2× faster, size on 'document' 25% smaller (matching tinycbor byte-for-byte), and a new libcbor-stream row that is ~3.5–5.8× faster still on encode. Changes in this commit: * Rename the existing row from "cbor-encode" to "libcbor" so it lines up with the vendored library's actual name. * Drop the tinycbor cross-dependency from the libcbor rows. Add ser_libcbor_common.c with bench_libcbor_de, a libcbor DOM-based decoder using cbor_load + cbor_map_handle / cbor_array_handle. Both rows now use it in place of bench_tinycbor_de. * DOM wrapper (ser_libcbor.c): use narrowest-width integer builders (cbor_build_uint8/16/32/64 and negint equivalents) instead of always emitting uint64/negint64. This is the RFC 8949 §4.2.1 preferred serialization; it removes the 25% size regression on 'document' and ~9% on 'message' that the row was showing on the published chart. * DOM wrapper: install a bump arena via cbor_set_allocs and reset it at the start of every ser() and de() call. This is the documented libcbor pattern for hot loops; it removes most of the per-item malloc cost that dominated the DOM path's time. Combined with the narrowest- width change, DOM encode drops from ~3.5–7× slower than tinycbor to competitive. * New row: libcbor-stream, wrapping libcbor's streaming encoder (cbor_encode_map_start / array_start / uint / negint / bool / double / string_start in src/cbor/encoding.h). Zero cbor_item_t allocations, no refcount traffic, no second serialization walk. This is the fair apples-to-apples peer of tinycbor / qcbor / zcbor streaming encoders. Output is interoperable CBOR and matches tinycbor's bytes exactly on every fixture in the suite. All 111 roundtrip checks in c_serializer_tests pass for both rows. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * libcbor-stream: address review — header + bool + catalog Follow-up on PR feedback: * ser_libcbor_stream.c: rewrite the stale file-header comment. It claimed decode reused the tinycbor visitor reader and that the wrapper still kept an indef stack; both were true of an earlier version and neither is true now. Also guard w_begin_map / w_begin_array against a negative count: v2_write_fixture never passes one today, but a future -1 would silently wrap to (size_t)-1 and emit garbage. * ser_libcbor_stream.c: emit booleans via cbor_encode_bool instead of poking 0xF4 / 0xF5 directly, so the row stays "only libcbor ops". Same two bytes, no measurable perf impact. * config/benchmark_config.yaml, c/third_party/VERSIONS.md, docs/c/index.md: update from the old "cbor-encode" name to "libcbor" and "libcbor-stream" so the catalog matches the row names the C runner logs. Splits the libcbor entry into two rows in the YAML catalog. All 111 c_serializer_tests roundtrip checks still pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: leo-gan <leo.gan.57@gmail.com>
* docs: rename Method tab to Benchmarks and fix Benchmarks links Reorder top tabs to Learn, Languages, Benchmarks, Dashboard, Experiments. Put Adding a Serializer and Adding a Language last under Benchmarks. Point Test Data and methodology config links at GitHub so they work on the published site. * docs: point language-index source links at GitHub Registration, README, and runner files live outside the MkDocs tree, so relative ../../lang/... links 404 on the site. Use blob/tree URLs on master, matching the Benchmarks Test Data table fix.
Move jspbEncode onto the timed path so the three JavaScript Protocol Buffers rows measure the same work. Rewrite the Serialization 401 articles in plain textbook English and refresh the JavaScript Dashboard slice.
* Document the timing contract and stop caching simdjson encode Add Timing honesty as the suite rule for prepare vs serialize. Move simdjson encode to nlohmann dump on the clock, and clone avsc payloads in prepare so timed serialize is only toBuffer. * Apply the timing contract to remaining dishonest wrappers Move JS remaps to untimed toDomain, convert Rust prost messages in prepare_many, walk C++ JSON DOMs instead of parsing twice, return C# JSON as text, and label Python buffer-then-write streams as adapted. * Time Java and Swift 401 pairs as suite value to suite value protobuf-java and SwiftProtobuf now convert on the timed path so each pair matches Protostuff and FlatBuffers: Document in, bytes, Document out. * Add prepare-and-approve-pr skill Land a feature branch: run prepare-pr, approve, fix failed checks, squash-merge, delete the PR branch, and sync local master. * Simplify dataclass comparison in the Python comparer Extract field reading so _compare_dataclass no longer branches on actual type. Compare only when expected is a dataclass, and drop dead missing-expected-field checks. * Drop stale DateTime TODOs and test Python log aggregation Suite payloads use integer timestamps, so the leftover DateTime TODOs on FsPickler and ServiceStack were misleading. Restore NativeKind/StreamMode on LogStorage.read_all and cover write/read, averages, and error dedup. * Size Java Cap'n Proto write buffer off the clock The strings N=100 cell overflowed the fixed 64 KiB ArrayOutputStream. Measure the needed size in prepare and refresh dashboard payloads from the full re-bench of the languages this branch changed. * Rename C# protobuf map alias to avoid CS0576 on CI The hosted SDK treats using Pb = Benchmark.V2 as a conflict with the generated pb alias. Use Wire instead.
Replace slang and clipped phrases on all thirteen experiment cards with complete sentences for a high-school reader. The Dashboard catalog picks up the same copy. Record the writing rule in STYLE.
* Add Kotlin as a tenth benchmark language with 26 serializers.
New kotlin/ Gradle harness (JDK 21) follows the Java prepare/timed/fidelity
contract. Roster covers the kotlinx.serialization format family, JVM JSON
and binary stacks, schema codecs (protobuf-java, protobuf-kotlin, FlatBuffers,
Cap'n Proto, Avro/Avro4k, Thrift), and kaml YAML. Register the runner in
config, CI, dashboard, docs, and analysis fallbacks.
* Fix Kotlin kbson and tomlkt batch encoding.
BSON cannot have an array at the document root, so N>1 cells are wrapped
as { batch: [...] }. tomlkt also uses that wrap key so nested Document.items
does not collide with the batch field and trip the parser.
* Publish Kotlin dashboard data and a 401 comparison page.
Pack the all-single Kotlin run into dashboard/public/data so the language
selector has stats. Sort the catalog alphabetically. Register Kotlin on
experiment 1 and add a 401 article that pairs Protostuff with the two
official protobuf rows on the same 155-byte document.
* Add Kotlin to experiments 2–13 and two more 401 pages.
Wire a Kotlin language block and run.sh into every remaining lab experiment, and register the Kotlin runner in each parent run.sh (including Experiment 1). Add 401 articles for kotlinx-json vs Moshi and FlatBuffers vs protobuf.
* Publish Experiment 1 Kotlin results on the Dashboard. Experiment 1 already listed Kotlin in experiment.yaml, but the Dashboard tabs come from results.json. Run the Kotlin bakeoff, keep other language summaries when no CSV is on disk, and sync the experiment catalog. * Time Kotlin on all experiments and require that in prepare-pr. The Experiments Dashboard tab only lists languages with summarized results. Run experiments 2–13 for Kotlin, keep other language pages intact, and add prepare-pr step 7 so changed languages are timed on every experiment that enables them.
* Add PHP as an eleventh benchmark language Register PHP in every closed-set consumer and add a Java-shaped CLI harness (PHP 8.3) that times official codec APIs only. Live rows are stdlib json, serialize, rybakit-msgpack, google/protobuf, Symfony JSON and XML, JMS JSON, CBOR, Avro, and Symfony YAML. PECL codecs register when the extension is loaded. Time the full 100-rep matrix (stem 2026-08-28-113418, 20k rows, no error-CSV regressions) and all 13 lab experiments. Pack Dashboard php_latest / stats_php_latest plus the experiment catalog. Add a 401 article comparing json_encode with official protobuf on document n=1. Update ADDING_A_LANGUAGE so a new runner is registered everywhere, experiments are timed, and dashboard gzip of other languages is not churned. * Add PHP to the site home Languages table docs/index.md still said ten runners and omitted PHP. Insert the 15-serializer row in alphabetical order and list this table in the add-a-language checklist. * Bump README language count to 11 Match the PHP roster: badge 11 and the lead sentence already says 200+ libraries across 11 languages.
* Add Zig as a twelfth benchmark language Native Zig 0.16 runner with the mixed candidate list: official std.json (two APIs) and std.zon, in-tree comptime-bin, serde.zig across JSON / MessagePack / YAML / TOML / ZON / XML, zig-msgpack, msgpack.zig, zbor, and s2s. Schema codecs (protobuf, FlatBuffers, Cap'n Proto) stay out until their 0.16 codegen paths exist. * Add Zig protobuf, FlatBuffers, and Cap’n Proto from shared schemas Generate suite types from the same .proto / .fbs / .capnp files other languages already compile. Wire honest prepare/encode/decode rows and drop the intake-list selection table from the Zig overview. * Publish Zig full-run dashboard and experiment results Full Zig bench (17 serializers, stem 2026-08-28-173322, 0 error rows) plus timed Zig rows for experiments 1–13. * Link Cap’n Proto against libstdc++ for CI Official libkj.a is built with GCC. Zig’s -lc++ does not provide std::exception_ptr, so zig build test failed on GitHub Actions. * Pass -lstdc++ (not Darwin -needed-lstdc++) for Cap’n Proto GitHub Actions still missed GCC exception_ptr symbols after the first link tweak. Emit a normal Linux stdc++ / gcc_s link line. * Build Cap’n Proto with system c++ into libzigcapnp.so Zig’s LLD cannot resolve GCC exception_ptr from libkj.a. The system compiler now produces a shared C ABI; Zig links only that .so.
The Zig squash also edited schemas/v2/README.md. dorny treated schemas/** as a hit for every language, so the master push ran all smokes. Match only the catalog and .proto contracts, same prose rule as detect-changed-langs.
…obs? (#135) * feat(experiments): add a starter-kit experiment across twelve languages Experiment 14 times a short list per language for typical jobs: public JSON, compact internal MessagePack, and a shared Protocol Buffers file. It is a place to begin, not a prize. Run logs stay local. * docs(experiments): link Experiment 14 pull request in the plan
Explain what each language platform is, what this suite actually runs, and what changes the numbers, so newcomers can read a language page without already knowing that runtime.
* fix(cpp): time Cap'n Proto encode/decode like libprotobuf Building the MessageBuilder and walking fields back to suite structs was on the clock, while protobuf did that work in untimed prepare/to_domain. Move fill to prepare, keep a reused builder, time messageToFlatArray/writeMessage and reader setup, and convert in to_domain. Addresses capnproto/capnproto#2730. * chore(cpp): refresh full bench, experiments, and dashboard Re-bench C++ after the Cap'n Proto prepare/to_domain split (stem 2026-09-04-111531), retime experiments that enable cpp, and publish cpp_latest dashboard payloads.
* Add Mojo as a thirteenth benchmark language Wire a pixi/Mojo 1.0 harness (EmberJson, ehsanmok-json, mojo-cbor, mojo-protobuf, mojo-avro, mojo-toml) through config, analysis, CI, experiments, and docs. CBOR/Protobuf are vendored under renamed packages to avoid conda module collisions; Avro and EmberJson stay conda packages. * Publish Mojo full-run dashboard and experiment results Sync mojo_latest from stem 2026-09-08-155242 and time experiments 01–14 for the new language so the dashboard catalog lists Mojo as ok.
* fix(zig): decode into the trial arena instead of a nested one The Zig runner already gives every trial a fresh ArenaAllocator and frees it after the measurement, but three adapters call the arena-wrapping entry point of their library, which heap-allocates and initialises a *second* arena on every call: std.json parseFromSlice std.json.scanner parseFromTokenSource msgpack.zig decodeFromSlice The result is dropped immediately -- only .value is kept -- so the nested arena buys nothing and is pure per-call overhead. It also leaks in the general case, since the returned Parsed is never deinit'd; here the trial arena happens to reclaim it. Each of these libraries has a *Leaky variant meant for exactly this situation. std.json documents it on parseFromSlice: "If you are using a std.heap.ArenaAllocator or similar, consider calling parseFromSliceLeaky instead." The adapters that take an allocator directly -- zbor, s2s, std.zon, zig-msgpack -- never paid this and are unchanged. .allocate = .alloc_always is kept on the std.json calls, so string ownership is unchanged; this only removes the redundant arena. Measured with all-single on this machine (Zig 0.16.0, ReleaseFast, median TimeDeser over reps 1..9, warmup rep dropped as the analysis does): std.json 2-19% faster std.json.scanner 4-19% faster msgpack.zig 8-40% faster The spread is expected: the nested arena is a roughly fixed per-call cost, so it is a larger fraction of a faster decoder. It is also why the effect is largest at data_type_instance_count=100, where deserializeCell calls the adapter once per item. Two cells change sign against protobuf: event/N=100 goes 1.25x -> 0.76x and message/N=100 goes 1.23x -> 0.97x. protobuf, zbor and s2s are untouched and move only 1.3-2.8% median between runs, so the changes above are well outside run-to-run noise. FidelityScore stays 1.0 on every row and no errors file is produced. * build(zig): pin msgpack.zig to the v0.9.0 tag The dependency pointed at refs/heads/master, which GitHub redirects to main, so the suite tracked whatever was on the branch while reporting version 0.7.0 in the results. Two runs months apart could measure different code under the same label. v0.9.0 is tagged, so pin the tag and correct the version the registry reports.
…nt (#140) Adds a second benchmark row for shamaton/msgpack using its struct-as-array encoding (MarshalAsArray/UnmarshalAsArray, MarshalWriteAsArray/UnmarshalReadAsArray). This drops field-name keys entirely, giving a more compact wire shape closer to schema-based formats (avro/protobuf), and is worth comparing separately from the default map-based shamaton/msgpack entry.
Vendor gld-json as gldjson_* so it can share a pixi env with mojo-avro. Wire expected-order encode/decode into the runner and roundtrip tests, register the row in config and experiments, and refresh Mojo dashboard payloads from full run 2026-09-09-131928 (fidelity 1.0).
Official n=1 document/strings/telemetry were 411–491 bytes written into a 256-byte WireWriter. Vendor gld-json #8 string/list path.
Re-vendor gld-json #9. Telemetry n=1 deser 2490→1678 ns.
Vendor gld-json one-pass number parse, 4-digit SWAR, Ember ctz SIMD scan, digit-pair itoa, and skip of the short-dtoa exact search. n=1 encode cap is 1024 so list ensure does not resize. Decode lists are pre-sized to n. Official 2026-09-09-160305 vs #145: telemetry n=1 deser 1678→1233 (1.35× Ember), n=100 167450→106745 (1.48×). Telemetry n=1 ser 2020→1319 (1.27×), n=100 195051→117007 (1.53×). Message n=1 deser 406→348 (1.55× Ember). Fidelity 1.0. Version stays 0.2.0.
Author
|
Wrong target: previous mojo-json speed PRs land on leo-gan/GLD.SerializerBenchmark (origin), not this fork-upstream PR. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
count_trailing_zerosSIMD scan, digit-pair itoa, and skip of the short-dtoa exact searchensureresized mid-encode)nMeasure (official all-single
2026-09-09-160305vs leo-gan#145)Fidelity 1.0. Strings deser is still heap-bound (32
Strings). Version stays 0.2.0.Validation
pixi run testinmojo/(roundtrip ok)./mojo/scripts/run-benchmarks.sh all-single jsonstem2026-09-09-160305