ReviewOS

zig-utils/zig-js

Bench: define the representative dependency-free performance matrix

#460
Closed chris opened this 8 days ago ·
8 days ago

Parent: #459

Goal

Define and implement the representative, dependency-free benchmark matrix that must be won before zig-js can claim broad performance leadership.

The completed #44 matrix is rigorous but deliberately narrow: ten small kernels centered on numeric loops, properties, object churn, arrays, calls, closures, arguments, and recursion. It does not measure large or mixed application behavior.

Scope

  • Add repository-owned workloads for strings/Unicode, RegExp, JSON parse/stringify, Map/Set/Weak collections, typed arrays/DataView, promises/async/microtasks, modules and dynamic import, classes/private fields, iterators/generators, proxies/accessors, Intl, Temporal, WebAssembly scalar/SIMD/memory, and mixed long-lived object graphs.
  • Pre-register and freeze the workload manifest, per-row success criteria, exclusions, and non-regression floors before implementation work uses a row as an optimization target. A later methodology change creates a versioned new baseline; it never rewrites a losing row in place.
  • Include cold startup, warm steady state, tier-up, deoptimization, context lifecycle, latency distribution, peak/retained RSS, generated-code bytes, GC pauses, and 1/2/4/8-lane scaling where meaningful.
  • Integrate work-efficiency/thermal panels from #503 and independent out-of-tree suite validation from #504 without making either a library/build dependency.
  • Use exact identical source/input bytes and deterministic checksums across zig-js and JSC. Where the public programming models differ, publish separate capability panels rather than false ratios.
  • Keep workloads authored in zig-js or another zig-utils-owned local repository. Do not vendor or download a benchmark suite as a production/dev dependency.
  • Add anti-specialization variants that change identifiers, source layout, data distributions, receiver shapes, loop structure, and call graph while preserving equal work.
  • Version the workload manifest, job counts, warmup protocol, hardware/toolchain metadata, and acceptance floors.

No-workaround rules

  • No source string, function name, benchmark name, checksum, fixed input, or call-site recognition.
  • No disabling GC, barriers, checks, watchdogs, debugger hooks, or synchronization on scored paths unless the same public mode disables them for both engines.
  • No unbounded caches/pools and no hidden precomputation outside the declared timed boundary.
  • No aggregate-only success: every row remains visible and must meet its own gate.

Acceptance

  • A machine-readable manifest defines every workload, mode, jobs, warmups, expected checksum, and metric.
  • The manifest and row-level win/non-regression criteria are checked in and reviewed before optimization begins; revisions preserve the prior matrix as history.
  • Full runs enforce a 50 ms timing floor or an explicitly justified latency protocol, alternating order, repeated samples, dispersion, and exact checksum equality.
  • Raw evidence and generated reports are reproducible from a clean worktree.
  • Anti-specialization variants produce equivalent tier attribution and no benchmark recognizer exists.
  • #504 corroborates the repository-owned matrix with independent workloads and explicit applicable/excluded inventories.
  • The original #44 matrix remains unchanged and green as a permanent compatibility panel.
  • The expanded matrix is reviewed and frozen before #459 evaluates “win every benchmark.”

Foundation

8 days ago

Initial representative-matrix foundation landed on main:

  • 9a7771bf freezes zig-js-representative-v1, hash-pins the original #44 compatibility panel, and adds 12 dependency-free workload families plus structural variants. The driver covers direct warmed, independent steady/cold, and zig-js shared-realm modes at 1/2/4/8 lanes; it enforces exact checked-in checksums, deterministic engine-order alternation, seven full samples, and the 50 ms full-row floor.
  • c95a4d4c fixes a genuine GC ownership bug exposed by the shared Intl row: managed bytecode constants were not traced through arena-owned chunks and could be collected/reused. The fix covers ordinary/generator/async/nested/active chunks and adds structural plus end-to-end regressions.

Validation completed:

  • zig build benchmark-comparison-test
  • complete --quick representative run across both engines and every implemented mode/lane
  • focused compiled-literal GC and Function relocation tests

The issue remains open. The manifest explicitly pre-registers six deferred families (promises/async/microtasks, modules/dynamic import, Temporal, and three Wasm panels) and the pending metric panels owned by #461, #503, and #504. Clean full evidence, tier-attribution equivalence, the deferred rows, and independent corroboration still need to land before the acceptance list is complete.

8 days ago

Landed the representative-v2 tier-attribution slice on main:

What this now proves:

  • attribution is opt-in and collected in fresh contexts outside scored timing rows;
  • every implemented base/structural-variant pair selects the same non-empty tier set during warmup and invocation;
  • exact environment allocation counts must match too (for example classes are 300/300 per phase and iterators 1,600/1,600);
  • the manifest hash-inherits frozen v1 timing/workload/checksum decisions and audits engine source for workload-specific recognizers.

Validation is green: 1,501/1,501 units, focused TSan witness, all benchmark harness self-tests, the 24-workload quick matrix, the full attribution matrix, docs, and 53,175/53,175 Test262 cases. This completes the instrumentation/variant-equivalence portion; clean before/after timing history, deferred families, metric panels, and independent corroboration remain open.

8 days ago

Landed the representative scalar-WebAssembly slice on main:

V3 hash-inherits the complete V2 contract and moves wasm_scalar from deferred to implemented without rewriting V1/V2 or the accepted SIMD history. Both engines evaluate the existing byte-identical Wasm source/module. The structural variant reverses JavaScript invocation order while preserving the exact scalar export and input multiset; frozen checksums cover quick/full jobs at 1/2/4/8 lanes.

Validation completed:

  • full zig build benchmark-comparison-test aggregate harness gate;
  • ReleaseFast comparison runner build;
  • complete quick matrix across both engines, direct/steady/cold modes, 1/2/4/8 lanes, and zig-js shared-realm mode;
  • base/variant tier equivalence (vm_entries+optimizer_entries) and environment-allocation parity;
  • zig build docs-link-check (91 files) and checked bun run docs:build (49 pages).

Implemented representative coverage is now 13 families; explicit deferrals are down from six to five. This quick run is validation only and publishes no timing claim. The issue remains open for promises/microtasks, modules/dynamic import, Temporal, Wasm SIMD/memory, full clean timing history, metric panels, and independent corroboration.

8 days ago

Landed the representative fixed-width SIMD slice on main:

V4 hash-inherits V3 and moves wasm_simd from deferred to implemented without changing earlier manifests or the accepted July SIMD evidence. Both engines use the existing byte-identical module. The scored i32x4 export retains its equivalent scalar export in the same module as the checksum oracle; the structural variant reverses JavaScript invocation order over the identical Wasm input multiset.

Validation completed:

  • full zig build benchmark-comparison-test aggregate harness gate;
  • ReleaseFast comparison runner build;
  • complete quick matrix across both engines, direct/steady/cold modes, 1/2/4/8 lanes, and zig-js shared-realm mode;
  • exact frozen checksum equality in every row;
  • base/variant tier equivalence (vm_entries+optimizer_entries) and environment-allocation parity;
  • zig build docs-link-check (91 files) and checked bun run docs:build (49 pages).

Implemented representative coverage is now 14 families; explicit deferrals are down from five to four. The quick run remains validation only and publishes no timing claim.

8 days ago

Landed the WebAssembly memory slice on main in 307e5b52.

This advances the frozen representative contract from V4 to V5:

  • implemented families: 14 -> 15
  • explicit deferrals: 4 -> 3
  • cross-engine non-shared v128 memory rows with an order-reversed structural variant
  • separately scored same-module scalar-memory oracle across zig-js and JavaScriptCore
  • genuine shared-memory disjoint-atomic capability rows for zig-js at 1/2/4/8 workers
  • an actual system-JSC probe must reject with JavaScriptException before the capability panel reports JSC as N/A; no synthetic throughput ratio is constructed
  • the non-shared module is never concurrently mutated

Validation completed:

  • complete V5 quick matrix across every inherited and new row
  • representative tier equivalence for the new base/variant
  • zig build benchmark-comparison-test
  • representative matrix structural tests: 8/8
  • zig build docs-link-check: 91 files
  • bun run docs:build: 49 pages against the regenerated manifest
  • 0 Test262 flips (benchmark/docs-only surface)

Quick mode was used only for execution validation; no quick timing is promoted as publication evidence. Remaining deferred families are promises/async/microtasks, modules/dynamic import, and Temporal.

8 days ago

Landed the Promise/async/microtask slice on main in 12aff9dd.

V6 hash-inherits the complete V5 contract and moves promises_async_microtasks from deferred to implemented:

  • implemented families: 15 -> 16
  • explicit deferrals: 3 -> 2
  • identical source bytes cover direct Promise reactions, chained reactions, thenable assimilation, and a two-stage async/await continuation
  • both public runners time invocation, their normal end-of-script host checkpoint, and the same generic post-checkpoint checksum read
  • synchronous historical rows retain their original one-evaluation path
  • the structural variant traverses the scheduling call graph in reverse order with identical work and checksums
  • zig-js shared-realm rows keep per-lane state and rely on the existing Thread completion contract that drains each worker queue before join settles

The full contract uses 60,000 jobs/lane. Live JSC calibration put its direct rows around 64 ms, safely above the 50 ms floor; a full zig-js probe and JSC produced the same exact checksum (115069600 at one lane). The current zig-js row is intentionally slow and remains visible for later optimization.

Validation completed:

  • complete V6 quick matrix across every inherited/new row, both engines, all applicable modes, and 1/2/4/8 lanes
  • new base/variant tier and environment-allocation equivalence
  • full-size cross-engine checksum probes
  • zig build benchmark-comparison-test
  • representative matrix structural tests: 10/10
  • zig build docs-link-check: 91 files
  • bun run docs:build: 49 pages
  • 0 Test262 flips

Quick and dirty-worktree timings were used only for calibration/validation and are not publication evidence. Remaining deferred families are modules/dynamic import and Temporal.

8 days ago

Landed the Temporal slice on main in 24da9b8d.

V7 hash-inherits V6 and moves temporal from deferred to an implemented availability-gated capability family:

  • implemented families: 16 -> 17
  • explicit deferrals: 2 -> 1
  • deterministic ISO/UTC PlainDate construction/addition, Instant parse/addition, and Duration construction/total
  • separate forward/reverse implementations change identifiers, loop direction, object property order, and operation order while retaining exact equal work/checksums
  • every run evaluates the same availability profile through both public runners
  • required live profile: zig-js=1, system JavaScriptCore JSGlobalContext=0
  • JSC is therefore reported as N/A; the scored workload is never conditionally changed and no ratio is constructed
  • zig-js direct and shared-realm rows remain visible at 1/2/4/8 lanes

The full workload is 650 jobs/lane. Live base/variant direct probes and every shared lane cleared the 50 ms floor and matched the frozen checksums.

Validation completed:

  • complete V7 quick matrix across every inherited/new row and availability gate
  • Temporal base/variant tier and environment-allocation equivalence
  • full-size direct and 1/2/4/8 shared checksum/floor probes
  • zig build benchmark-comparison-test
  • representative matrix structural tests: 12/12
  • zig build docs-link-check: 91 files
  • bun run docs:build: 49 pages
  • 0 Test262 flips

Quick and dirty-worktree timings remain validation/calibration only, not publication evidence. The sole remaining deferred workload family is modules/dynamic import.

8 days ago

Landed https://github.com/zig-utils/zig-js/commit/a1b5c393e48690c35f2882ec90f288fc3b629d6 on main.\n\nThis completes the frozen representative workload inventory at 18/18 families with 0 explicit workload deferrals. V8 adds owned base and structural-variant ES module graphs covering static linking, host resolution, top-level dynamic import, microtask settlement, cold context teardown, and exact 1/2/4/8-lane checksums. The system JSC side is kept as a runtime-gated N/A: every run requires its public JSGlobalContext runner to reject the exact module-syntax probe, and the installed public SDK has no module evaluation or host-loader entry point. No private SPI, source transform, or script emulation is used.\n\nValidation: zig build benchmark-comparison-test; zig build docs-link-check (91 files); bun run docs:build (49 pages, manifest reproduced). Flips 0 test262 cases.\n\n#460 remains open for the metric panels tracked by #461/#503, the independent corroboration tracked by #504, and a clean full-history publication run.

8 days ago

Full V8 tier corroboration landed in https://github.com/zig-utils/zig-js/commit/44b097e: all 18 families / 36 base-variant workloads / 108 phase snapshots passed frozen checksum, tier-equivalence, and environment-parity gates at full job counts. The older V2 artifact was preserved rather than rewritten. #460 remains open for non-tier metric panels and independent-suite corroboration.

8 days ago

The full representative V8 sidecar now includes native-code lifetime/invalidation and precise-heap residency/collection state for all 18 families in https://github.com/zig-utils/zig-js/commit/e5b5640b1e4577d109f42aa4532ae141bcce3a82 (108 exact-revision snapshots). This advances #460 metric coverage through #461, while CPU/RSS/allocation-rate, pause distributions, #503 efficiency, and #504 independent-suite evidence remain open.

8 days ago

The representative attribution contract advanced to V14 in 80d9af1c without changing any frozen scored workload, mode, jobs, checksum, timing boundary, availability ruling, or acceptance decision.

The anti-specialization gate now checks base/variant tier-set and environment-allocation equivalence independently for every supported single/module and 1/2/4/8-lane shared row. Both additional-panel workloads are included instead of being omitted from attribution. The real quick matrix passed all 170 executions / 510 snapshots and exact lane-specific checksums; full-work schema-8 publication remains pending.

8 days ago

Full V15 representative attribution is now checked in through implementation 549ff01f and evidence 96220688.

The complete schema-v10 artifact covers all 18 frozen families plus both additional workload panels: 170 full-work executions, 510 phase snapshots, exact checksums, base/variant tier and environment parity, tier-up/deoptimization latency, allocation operations/bytes, exact GC pause distributions, runtime dispatch, process CPU/RSS, synchronization, heap/native-code lifetime, and lane-specific shared attribution. It is one uninterrupted complete collection; the older incomplete attempt was not promoted or rewritten.

The run used the exact committed workload contract and passed all 170 executions without changing a scored job, checksum, mode, timing boundary, availability ruling, or acceptance criterion. This completes the full-work causal-attribution sidecar for the current representative matrix. #460 remains open for clean repeated cross-engine timing publication, #503 efficiency/thermal panels, and #504 independent-suite corroboration.

8 days ago

The first clean full V15 timing publication attempt exposed a real engine blocker at representative_collections, shared realm, four lanes; the collector failed closed and wrote no evidence. I tracked it as #510 and fixed it in 9d0227a3: captured VM frame slots were omitted from Function tracing/relocation, leaving stale moved StringCell addresses.

The exact formerly failing seven-sample row now passes three consecutive runs (21/21 samples, frozen checksum 450464400), with focused/full unit and TSan mid-GC coverage green. I am resuming the clean full publication run from this fixed revision; no partial output from the failed run was promoted.

8 days ago

The moving-GC correctness blocker in the async/microtask row is fixed on main by 33150087, closing #511. The exact bounded eight-lane workload now passes 7/7 ReleaseFast samples with a stable checksum.

The restored row exposed a separate full-scale retention/performance problem: seven bounded samples reached 2,787,491,840 bytes maximum RSS, while the 60,000-job publication-scale diagnostic exceeded an hour and reached roughly 20.5 GB physical footprint while workers remained active in GC/Promise work. I opened #512 with the exact evidence and no-workaround acceptance criteria.

Publication remains blocked on #512; rerunning the full matrix before that lifetime issue is fixed would reproduce an unpublishable, host-stressing run.

8 days ago

The first full-scale async/microtask memory slice is now on main as 6b49bf45, tracked by #512.

It removes two generic side allocations from every ordinary Promise wrapper while preserving C-API host private data and moving-GC relocation. On the exact eight-lane 6,000-job seven-sample row, median wall improves 11.0% from 2.587441667 s to 2.303243500 s and maximum RSS drops from 2,787,491,840 to 2,752,856,064 bytes with the checksum unchanged.

Publication is still blocked on #512. The new profile identifies 576,000 promises and 9,748,601 uncontended Promise locks in one bounded sample; the 60,000-job publication row has not yet produced acceptable bounded memory/time evidence.

8 days ago

Progress on the async timing blocker: perf(promise): elide serialized state mutexes (#512) removed 9,748,601 uncontended Promise mutex acquisitions from a bounded eight-lane sample.

At 6,000 jobs × 7 samples × 8 lanes, median elapsed improved 4.2% (2.303243500s → 2.205518875s), maximum RSS fell 15.4% (2,752,856,064 → 2,327,691,264 bytes), and checksum stayed 91956096. The concurrent path remains locked and passes its TSan stress test.

#460 remains blocked on #512 until the full 60,000-job representative timing completes with acceptable memory.

8 days ago

perf(gc): amortize nursery scans over job roots (#512) makes the first publication-scale async sample complete: measured workload time falls from 422.708234500s to 36.310953209s (11.6×), with checksum 920578560 unchanged.

The exact seven-sample row is not yet publishable. After 1,248.43s it had reached 19.2 GB physical footprint and was again dominated by young-GC tracing across active lanes, so the diagnostic was interrupted. #460 remains blocked on #512 while cross-sample promoted-heap retention is fixed.

8 days ago

The full timing blocker is removed by perf(gc): reclaim quiescent promotion debt (#512), which closes #512.

The exact ReleaseFast representative_async_microtasks row now completes 60,000 jobs × 7 samples × 8 independent lanes in 217.76 s process real time. All seven checksums are the frozen 920578560; measured workload times are 49.304156125, 42.738223667, 50.622881625, 26.409281125, 12.020120208, 11.698269417, and 14.347988875 seconds, with median 26.409281125 s. Maximum RSS is 8,001,585,152 bytes and peak physical footprint is 18,089,916,888 bytes.

The collector now reclaims promoted burst garbage from a trusted quiescent live baseline instead of allowing a transient mid-burst old-generation threshold to suppress the next full sweep. Full units pass 1,537/1,538 with one expected skip and no failures or leaks.

I am resuming the clean, complete representative V15 timing publication from this exact main revision. No partial diagnostic output from the earlier blocked attempts will be promoted.

8 days ago

The #513 implementation landed in c797973a. It changes the Map/Set index representation and adds structural growth evidence, but makes no timing claim. The required exact-parent representative_collections A/B and the complete V15 timing publication remain outstanding under #460; the detailed correctness evidence is recorded on #513.

8 days ago

The representative collections work gained a completed exact-parent chain in #514 / 363a643: eight schema-v1 raw/report pairs covering stable cursor compaction, capacity release, cursor hints, and insertion lock elision, each with 7 order-balanced pairs and matching checksums. The evidence is diagnostic-only because cache-miss counters were unavailable; it is useful input to the eventual frozen Map/Set row, not a substitute for the full cross-engine matrix required here.

8 days ago

#513 adds a reproducible object/Symbol strong-collection row and anti-specialization variant in a5558e2. Exact-parent evidence in 4adcc0d records about 0.619x instructions for both variants at identical checksums. These diagnostic rows inform the eventual frozen collections matrix; cache-miss counters were unavailable, so they do not make a cache-efficiency publication claim.

8 days ago

Added two schema-v1 exact-parent JSON rows in b0bcc993 for #516: seven order-balanced pairs each, matching identities/checksums, no discards, nominal thermal state. Retired-instruction ratios are 0.9787x and 0.9786x. Wall time is explicitly diagnostic-only (1.007x noisy base; 0.970x variant), peak RSS is mixed, and unavailable cache-miss counters support no cache claim.

8 days ago

Added a permanent callback-observable JSON reviver-source row in 7a842b3a without modifying the frozen representative-v1 matrix. The #517 schema-v1 exact-parent artifact uses seven order-balanced pairs and records 238.862 → 44.800 ms (0.188x) and 0.1248x instructions; cache misses are unavailable, so the report remains diagnostic and makes no cache claim.

8 days ago

Added a callback-observable escaped JSON string decision row in 9961a43. Its first exact-parent use is intentionally negative evidence: 500e67a records seven order-balanced pairs rejecting the managed-backing transfer at 1.021x wall and 1.0017x instructions, with matching checksums and no discards. The engine attempt was reverted; the row remains outside the frozen representative-v1 matrix.

8 days ago

Added validated exact-parent decision evidence for #519 at https://github.com/zig-utils/zig-js/commit/11833827. It records the isolated algorithmic gain (0.038x wall, 0.0336x instructions), the full-pipeline result (0.8661x instructions; wall sample explicitly too noisy), and the corrective bucket-lifetime comparison (45.5 MB to 34.3 MB median peak RSS, 0.999x wall). Energy and cache behavior remain unclaimed because counters were below resolution/unavailable.

8 days ago

Added three strict-parameter frontend growth rows plus parser-only isolation in #520: https://github.com/zig-utils/zig-js/commit/f2398f65 and https://github.com/zig-utils/zig-js/commit/ca7a2bf3. Validated exact-parent artifacts are published by https://github.com/zig-utils/zig-js/commit/39c617e4. The stable 4,096 full pipeline row is 0.126x wall and 0.0733x instructions; smaller wall rows remain diagnostic due noise. Energy and cache behavior are explicitly unclaimed.

8 days ago

Linked the next reflection-memory row as #521. It will add exact ordered-checksum workloads for wide ordinary objects, sparse arrays, and Proxy ownKeys validation before changing allocator lifetime, so CPU and memory decisions remain evidence-backed.

8 days ago

Bounded own-key work #521 is complete. Exact-parent ordered-object growth is now 0.194/0.404/0.670 ms at 1024/2048/4096 keys versus 2.089/11.328/58.745 ms, with stable instruction reductions and flat sparse/Proxy controls. Evidence and gates: /zig-utils/zig-js/issues/521#issuecomment-5245487200.

8 days ago

#528 adds five dependency-free representative rows: 8-item linear control, 1K/2K/4K unique CanonicalizeLocaleList scaling, and 4K duplicate-heavy input. Fixture creation stays outside the timed boundary and checksums are frozen. Seven-pair raw timing/instruction/cycle/energy/RSS artifacts are checked in under docs/.data/exact-parent-locale-list-*-2026-08-10.{json,md}.

8 days ago

#529 added frozen generic Array traversal rows and closed with exact parent/child artifacts. The implementation is memory-causal rather than a throughput claim while #530 remains: generic 1K/2K/4K wall ratios were 1.002x/0.978x/0.989x, sparse Proxy 1.024x, and the 15-pair dense control 1.001x wall / 1.008x instructions / 1.000x RSS. Raw/report index.

8 days ago

#530 published seven frozen exact-parent rows plus a retained-RSS panel in 21a33f13: 1K/2K/4K plain array-like growth, sparse Proxy, dense Array control, shallow classes, and mixed application. Every artifact records exact source/binary/dependency identities, checksum, order-balanced pairs, wall/CPU/instructions/cycles/energy/thermal/RSS, and keeps noisy wall evidence diagnostic rather than promoting it.

These rows remain useful inputs to #460; the broader matrix/versioned acceptance manifest is still owned here.

8 days ago

#556 added six frozen representative JSON.stringify rows (depth 512/1024/2048/4096, real 4K cycle, shallow 4K repeated-alias control) and completed 84-sample exact-parent publication in https://github.com/zig-utils/zig-js/commit/ac9dc52b . All checksums and identities matched; #558 reuses the depth rows for the separately measured nested-output copying path.

8 days ago

Related performance/security work #558 is complete: 3ec9847f makes nested JSON.stringify output linear in successful output construction, and 61652299 publishes exact-parent evidence. The depth-4,096 row uses 0.2341x retired instructions and 0.0311x median peak RSS, without changing the 66/66 Test262 result.

8 days ago

Representative JSON coverage advanced in #557 via 98972688: plain 4K/16K/64K, Unicode, sparse mixed escapes, lone surrogates, and short control rows now have frozen identities. Runtime/evidence landed in a7da43f4 and 6dbe188f.

8 days ago

#577 added three symmetric structural Intl rows in de5d3215: ListFormat, RelativeTimeFormat, and DurationFormat formatToParts.

Fixtures are outside the timed boundary and checksums consume complete type/value/unit structure. At 320 jobs, both engines clear the 50 ms floor and match exactly (650961865, 629639089, 588161046). The rows now provide the frozen exact-parent allocation boundary for the metadata-ownership implementation in #577.

8 days ago

The structural Intl benchmark rows frozen by #577 are now paired with the landed implementation 755095e2. All three rows retain exact zig-js/JSC checksums and explicit timed boundaries; exact-parent attribution records deterministic allocation/GC reductions. Order-balanced wall timing was mixed, so no throughput claim or matrix win was inferred.

8 days ago

Opened #578 to add the missing symmetric Intl.Segmenter iteration and containing() controls. The rows will consume complete segment/index/input/isWordLike structure with identical zig-js/JSC source and stable checksums before any ownership optimization.

8 days ago

#578 is complete on main: perf(intl): share Segmenter input values (#578).

This removes attacker-controlled full-input duplication from every Intl.Segmenter result by retaining one immutable, precisely rooted input Value across %Segments%, iterators, and records. At 100 jobs it removes 72,801 GC cells / 4,420,452 cumulative bytes from full iteration and 32,001 cells / 1,919,252 bytes from indexed containing(), without increased property locks or collections. Exact checksums, 79/79 Segmenter test262, focused suppression-free TSan, bounded heap, moving GC, shared-realm no-GIL, OOM, and full units all pass.

8 days ago

Opened #579 for the next independently measured Intl leaf. PluralRules.select() currently allocates a fresh GC string cell for every result even though the category vocabulary is closed to six values; resolvedOptions().pluralCategories repeats the same structural allocation. The child freezes steady select/resolved-category rows first, then uses immutable native category values with OOM, bounded heap, moving GC, no-GIL, TSan, full PluralRules/Intl402, and full-unit gates.

8 days ago

Completed #579 via perf(intl): intern PluralRules categories (#579), following the committed benchmark boundary 65dbcf2c.

Closed native category values remove 198,402 backing allocations/GC cells and 3 collections from steady select(), plus 396,802 allocations/cells and 7 collections from repeated resolvedOptions().pluralCategories at 100 jobs. Checksums and property-lock counts are exact; timings are neutral, so no latency claim is made. PluralRules remains 53/53, full Intl402 3,341/3,341, and focused normal/TSan/no-GIL/moving/bounded/OOM plus full units are clean.

8 days ago

Opened #580 for the next independently measured Intl leaf. Bound compare currently allocates/canonicalizes its already-normalized locale and reprocesses the internal options object on every call, multiplying configuration work during sort. The child freezes direct-compare and sort rows first, then reuses immutable instance state with coercion/OOM/bounded-heap/moving/no-GIL/TSan, full Collator/Intl402, and full-unit gates.

8 days ago

Collator correctness follow-up: #581 tracks the locale-weight divergences found during #580 performance differential (German phonebook and Thai ignorePunctuation semantics).

8 days ago

#580 completed on main: immutable GC-finalized Collator state, invocation-local freeable Unicode/numeric key storage, and dedicated direct/sort benchmark rows landed in 56bf8586, 9f1fbf48, and 92f9bc4a. Exact-parent medians improved 28.3% for both direct compare and bound sort; retained backing fell 91.1% and 85.8%, respectively. Collator 65 → 65, Intl402 3,341 → 3,341, full units 1,675 pass / 1 skip, focused TSan clean. Separate pre-existing locale-weight divergences are tracked in #581.

8 days ago

#581 completed on main in f54dea87: German phonebook/search case weights and Thai default/explicit ignorePunctuation now preserve accent/case distinctions. Expanded 121-case and original 128-case public matrices match system JSC sign-for-sign; Collator 65/65, Intl402 3,341/3,341, full units 1,676 pass / 1 skip, focused TSan clean. No repro-string special cases or unbounded caches were added.

8 days ago

The next Intl matrix leaf is frozen in #583 / 6f1e25f8: a public steady Intl.DisplayNames.prototype.of row with construction outside the timer, exact ordered string hashing, byte-identical system-JSC output, and a 624 ms reference timing at 100 jobs. Broader locale-data differences are explicitly tracked in #582 rather than admitted into the comparable row.

8 days ago

Completed the comparable DisplayNames steady row in #583 via 6f1e25f8 and 925075c8. The public checksum stays exact against system JSC; exact-parent attribution records -20.49% property locks, -33.00% current backing, and -8.00% retained RSS. Seven-pair wall medians improve 4.80% but remain diagnostic because of dispersion. The excluded locale-data gaps are tracked in #582.

8 days ago

The representative Intl.DisplayNames.of row now has its correctness/data boundary completed by #582 in 2b4449f6. Its exact-parent checksum stays 139703394, and property-lock, backing-allocation/byte, GC-cell, and collection counters are identical after adding construction-time locale indexing. zig build intl-displaynames-jsc-diff adds 9 byte-exact system-JSC rows, 2 explicitly frozen pinned CLDR/ICU deltas, and 11 exact resolvedOptions() controls.

8 days ago

RelativeTimeFormat attribution update from #584 / a3400953: the existing representative_intl_relative_time_format_parts row retains checksum 9262214; exact-parent property locks fall 2,338,798 -> 2,223,594 (-4.93%), GC cells 795,273 -> 795,270, and current/peak backing by 144 bytes with unchanged allocation count. Seven-sample medians are effectively flat (297,982,792 -> 299,063,542 ns), so this is synchronization/ownership evidence only, not a throughput improvement claim.

8 days ago

ListFormat attribution update from #585 / 6f8e770c: representative_intl_list_format_parts retains checksum 515925585; exact-parent property locks fall 4,706,794 -> 4,629,990 (-1.63%), backing allocations 2,439,308 -> 2,439,307, GC cells 1,390,458 -> 1,390,455, and current/peak backing by 1,266 bytes. Paired timing was high-variance and established no improvement, so this is synchronization/ownership evidence only.

8 days ago

Segmenter attribution update from #586 / d77dbd2b: representative_intl_segmenter_iterate_word retains checksum 360619407; exact-parent 5-sample median improves 2,745,043,333 -> 2,692,355,167 ns (-1.92%), property locks 15,705,190 -> 15,692,387, and GC cells 4,979,258 -> 4,979,257. The bounded formatter record adds one 40-byte backing allocation; Segments input/iterator lifecycle was not changed.

8 days ago

#587 landed in 33d6e55b. On frozen checksums, exact-parent medians improve 6.63% for PluralRules select and 3.93% for resolved categories; property-lock traffic falls 32.85% and 10.68%, respectively. Final GC-cell and collection counts are unchanged.

8 days ago

#588 adds the frozen DurationFormat resolved-state row in 406361e3. zig-js and system JSC agree on checksum 742401512; the existing parts checksum remains 58800326. Exact baseline allocation, GC, lock, and retained-memory counters are recorded in the commit and child issue.

8 days ago

The representative matrix now has frozen Intl.DurationFormat parts and resolved-state consumers from #588. 1cf4df26 preserves checksums 58800326 and 742401512; exact-parent attribution and six-pair order-balanced timing are recorded in the closing comment on #588. Parts timing is flat (+0.013%), while repeated reflection improves 1.59% and removes 268,814 backing allocations.

8 days ago

Added and completed the frozen Collator resolvedOptions() row in #589. Corrected boundary 3f3bb952 and runtime db8ef45b retain exact zig-js/JSC checksum 837300589. Exact-parent attribution removes 6.19% of property locks, 25,696 backing allocations, and 25,632 GC cells; two timing windows disagree, so the result is intentionally structural-only.

8 days ago

Representative Intl.Locale reflection boundary added in #590 by 71387a9e, then optimized in 28165f51. Frozen checksum is 967094315 at 10 jobs across zig-js/JSC (670943087 at 100-job attribution). Two balanced timing windows observed -0.85%/-0.53% medians; kept as diagnostic rather than a public throughput claim.

8 days ago

#591 landed in eb661dce. Exact-parent 100-job NumberFormat construction attribution: default backing allocations -19.0% and GC cells -16.7%; uncommon backing allocations -12.1% and GC cells -7.2%, with unchanged checksums and 3341/3341 Intl402.

8 days ago

#592 landed in da10d1f7. Across all four frozen 100-job DateTimeFormat construction rows, checksums/collections remain exact while property locks fall by 89,672 per row, backing allocations by 38,446-38,448, and GC cells by 12,816.

8 days ago

#593 landed in 724c3d73. All nine frozen 100-job representative rows preserve checksums/collections while each removes 112 property-lock acquisitions, 56 Shape transitions, 168 backing allocations, and 56 GC cells.

8 days ago

The frozen representative_temporal base/variant pair caught and bounded #594. b795eeb2 improves 21 order-balanced exact-parent medians by 23.00% (base) and 21.66% (variant), with exact checksums and unchanged allocation/GC/lock counts; the gain is specifically repeated duration-bag descriptor/prototype probing.

8 days ago

The frozen Temporal base/variant also bounded follow-up #595. 6be183d3 improves exact-parent medians another 16.80% / 17.75% after #594, with matching checksums and unchanged lock/allocation/GC attribution.

8 days ago

#596 is complete in c544df8e. Publishing Temporal native state through the Object hot private word removes 19,800 backing allocations per 100 representative jobs and improves exact-parent 1,000-job medians by 3.65%-3.66%, while preserving C API host attachment, OOM rollback, GC finalization, and all measured conformance.

8 days ago

Completed on main in 5a8afbe0.

The frozen representative contract is now V16:

  • all 18 required workload families remain implemented with 0 deferred families;
  • every V15 workload, mode, job count, checksum, timing boundary, acceptance rule, and tier-attribution contract is hash-inherited unchanged;
  • the #503 efficiency/thermal publication guard and #504 independent-suite corroboration stack are hash-pinned as completed panels;
  • pending metric panels fall from 2 to 0;
  • external-suite scores remain separate corroboration and never enter repository-owned aggregates;
  • missing hardware/energy metrics remain explicitly unavailable rather than becoming zero or synthetic values;
  • the original #44 compatibility matrix remains hash-pinned and unchanged;
  • full-run order balancing, seven samples, the 50 ms floor, per-row visibility, clean-tree publication checks, and exact checksum equality remain enforced;
  • base/structural variants retain full tier/environment equivalence, while the independent recognizer gate proves source-hash changes do not select a special execution path.

The fail-closed dependency inventory was also reconciled with the current graph: 15 classified edges, 65 TypeScript tools, and 0 migration targets. LLDB and Foundation thermal sampling are opt-in platform verification boundaries and are never linked into libzig-js.

Validation:

  • zig build benchmark-comparison-test
  • zig build dependency-audit
  • representative matrix mutation tests: 22/22
  • representative benchmark checksum/timing-floor self-test
  • zig build docs-link-check: 267 files
  • bun run docs:build: 49 pages
  • 0 Test262 flips; this is benchmark/tooling/documentation-only

This completes every acceptance item in #460 without publishing a new timing claim or rewriting historical evidence.

8 days ago

Completed on in .\n\nThe frozen representative contract is now V16:\n\n- all 18 required workload families remain implemented with 0 deferred families;\n- every V15 workload, mode, job count, checksum, timing boundary, acceptance rule, and tier-attribution contract is hash-inherited unchanged;\n- the #503 efficiency/thermal publication guard and #504 independent-suite corroboration stack are hash-pinned as completed panels;\n- pending metric panels fall from 2 to 0;\n- external-suite scores remain separate corroboration and never enter repository-owned aggregates;\n- missing hardware/energy metrics remain explicitly unavailable rather than becoming zero or synthetic values;\n- the original #44 compatibility matrix remains hash-pinned and unchanged;\n- full-run order balancing, seven samples, the 50 ms floor, per-row visibility, clean-tree publication checks, and exact checksum equality remain enforced;\n- base/structural variants retain full tier/environment equivalence, while the independent recognizer gate proves source-hash changes do not select a special execution path.\n\nThe fail-closed dependency inventory was also reconciled with the current graph: 15 classified edges, 65 TypeScript tools, and 0 migration targets. LLDB and Foundation thermal sampling are opt-in platform verification boundaries and are never linked into .\n\nValidation:\n\n- OK exact-parent self-test: identity, pairing, regression, and cleanliness gates verified OK representative tier attribution self-test: phases, checksums, tier/runtime/timing/synchronization/allocation/process inventory, exact GC pauses, environment parity, native-code lifetime, heap state, CPU, RSS, tier transitions, and exact checkpoint/resume identity verified gc-generation-benchmark self-test: ok wasm-threads-benchmark self-test: ok OK representative benchmark self-test: matrix, frozen checksums, and timing floor verified OK independent-suite collector self-test: child validation, lossless failures, valid-only dispersion, checkpoints, and fail-closed aggregate verified independent-suite zig-js adapter self-test: score, attribution, and anti-specialization modes passed independent-suite system JSC adapter self-test: passed OK benchmark publication self-test: history, noise, environment, and README gates verified OK performance-attribution self-test: schema failures and 168 legacy rows verified OK benchmark comparison self-test: matrix, checksum, timing, and publication gates verified build-feedback self-test: ok wasm-simd-benchmark self-test: ok OK object-churn GC profile self-test: telemetry, accounting, and findings verified OK independent-suite recognizer self-test: source-hash and tier-signature drift fail closed OK independent object-churn self-test: parsing, classification, and checksum rejection verified OK shared object-churn A/B self-test: telemetry, balancing, and publication finding verified OK instrumentation overhead self-test: parsing, alternation, checksums, capability states, calibration quality, and explicit boundaries verified representative matrix structural tests: 22/22 passed\n- \n- representative matrix mutation tests: 22/22\n- representative benchmark checksum/timing-floor self-test\n- docs-link-check: 267 files, all links resolve: 267 files\n- [?25l ⠋ Building documentation... ⠙ Building documentation... ⠹ Building documentation... ⠸ Building documentation... ⠼ Building documentation... ⠴ Building documentation... ⠦ Building documentation... ⠧ Building documentation... ⠇ Building documentation... ⠏ Building documentation... ⠋ Building documentation... [?25h✓ Built 49 pages to HTML in 981.880667ms: 49 pages\n- 0 Test262 flips; this is benchmark/tooling/documentation-only\n\nThis completes every acceptance item in #460 without publishing a new timing claim or rewriting historical evidence.

Sign in to comment on this issue.