ReviewOS

zig-utils/zig-js

Intl.DateTimeFormat: emit text without materializing parts

#573
Closed chris opened this 9 days ago ·
9 days ago

Problem

Intl.DateTimeFormat.prototype.format still builds a structural DtfPart list, allocates each formatted numeric field, optionally performs a second digit-translation pass over those parts, and then concatenates every part into the returned string. That work is necessary for formatToParts and interval analysis, but not for text-only formatting.

This remains after #572 compiled immutable resolved formatter state.

Scope

  • Introduce one authoritative DateTimeFormat emission algorithm with direct text and structural-parts sinks.
  • Stream text-only formatting directly into the final byte buffer, including non-Latin digit translation as fields are emitted.
  • Keep exact part boundaries for formatToParts and range formatting without duplicating locale/calendar/Temporal ordering logic.
  • Preserve coercion order, TimeClip errors, Temporal field restrictions, OOM behavior, GC safety, and read-only no-GIL sharing.
  • Measure exact-parent text/parts/range controls and retain exact test262 DateTimeFormat and Temporal results.

Out of scope

  • New CLDR interval-pattern coverage.
  • Constructor resolved-state work (completed in #572).
  • Promise/microtask/Worker/job lifecycle work.

Parent: #475 Depends on: #572

9 days ago

Landed on main in perf(intl): stream DateTimeFormat text emission (#573).

The retained implementation runs one ordered DateTimeFormat emitter through direct-text and structural-parts sinks. Text formatting no longer materializes DtfPart records; numeric fields use bounded stack scratch, numbering-system digits are translated during emission, and structural consumers copy ephemeral bytes before publication. formatToParts and range consumers keep their exact boundaries and share the same ordering logic.

Exact-parent evidence at 100 jobs:

  • all text/parts/equal-range/equal-range-parts checksums match the parent and system JSC;
  • text-consumer backing allocation bytes: 90,434,989 → 80,579,965 (−10.9%);
  • GC-cell allocations: 234,716 → 234,716;
  • collection count: 8 → 8;
  • timing windows were noisy, so no throughput ratio is claimed.

Verification on the committed source:

  • DateTimeFormat test262: 244/244;
  • Intl402 Temporal: 2029/2029;
  • built-ins Temporal: 4603/4603;
  • affected test262 flips: 0;
  • focused TSan DateTimeFormat group: 6 passed / 0 failed / 0 leaked, including moving GC and four-lane no-GIL sharing;
  • full unit gate: 1657 passed / 1 skipped / 0 failed / 0 leaked across 10 shards;
  • zig fmt --check and git diff --check: clean.

Sign in to comment on this issue.