Archive — history, not state. Kept for its reasoning and its evidence; its plan is closed.

Profiling axes: separating what carries to native from what doesn’t

Performance here has three distinct dimensions, and improvements must be attributed to the right one — VM-only wins must never be mistaken for wins that carry to AOT native code:

  1. Mcode in the hot path (carries fully to native): exact dispatched instruction counts per bench, now with per-opcode histograms ($runtime.op_counts(), gated by $runtime.count_instructions(true) — a 256-entry counter array bumped in the same untaken branch as the instruction counter; zero cost when off).
  2. VM dispatch efficiency (interpreter-only): ns per dispatched instruction, derived per bench (wall / instructions). A change that moves wall time but not instructions and not allocation is VM-only.
  3. Runtime services (carries fully to native — same allocator, GC, record hash, text machinery under AOT): allocation bytes/objects, GC cycles, and GC time (gc_ms, exposed through $runtime.vm_stats()), plus four service-targeted benches whose wall time is dominated by one service: record_lookup (hash hit/miss), record_grow (insert+rehash), text_search, gc_churn (collector throughput with a surviving live set).

All benches are plain pit programs, so the identical suite runs under a future AOT backend for direct comparability.

Baseline snapshot (M-series dev machine, gate = make budget):

benchmsinstrns/iallocGCs
numeric_loop7.311.0M0.661.0KB0
string_build0.3220k1.30330KB2
array_sweep2.52.60M0.972.1MB3
record_churn11.15.25M2.112.7KB0
closure_calls7.62.85M2.6610.8MB/150k135
record_lookup7.15.25M1.3447KB0
record_grow5.92.07M2.838.3MB/14k41
text_search1.2481k2.47969KB/20k5
gc_churn6.21.70M3.658.8MB/100k57

The ns/instr spread (0.66 pure arithmetic -> 3.65 GC-bound) is the axis separation working: services, not dispatch, dominate the heavy benches.

First finding surfaced by the new columns: text_search performs ~1 allocation per search() call (20,024 for 20k searches) — the search intrinsic allocates on hit, a runtime-services target that would carry to native.

Gating: instructions ±2%, alloc bytes ±5%, wall ±35%; gc count/time and ns/instr reported, not gated (heap-state / derived).

Source: plans/archive/perf-2026-07/2026-07-08-profiling-axes.md