XPerf
Guides

Rule regression coverage

As of 2026-10-22 (Asia/Shanghai). Null/reverse deep-dive landed (rb-hash-merge-in-loop fixture/msg; cx-string-append-unreserved / at-includes-hot docs; measured-useless tombstones; no severity escalate). Evidence fill batch A: goperf/pyperf/cppperf/phpperf/rustperf/luaperf/rubyperf; nim blocked. Contract: playbook.md § Rule regression. Per-kit gates: packages/*/docs/evidence-policy.md. Smells: smell-catalog.md.

Columns

  • bad / good: lint fixtures under packages/<kit>/*-lint/fixtures/
  • evidence: both .md + .jsonl under packages/<kit>/evidence/ (speed gate)
  • severity: package default / policy (cperf·jsperf --preset app; jvmperf policy map; zperf historically all findings fail CI)
  • pending measure: needs before/after JSONL before keep/escalate to error (siblings own benches — this matrix does not invent ratios)

Fixture pass proves the rule still fires; evidence proves it still means speed. Corpus residual counts ≠ either.


Scope (2026-10-27): default matching is --scope all (or kit-equivalent) across kits; opt in to --scope loop for the former loop-only behavior. Slugs formerly containing in-loop were renamed to *-hot and tombstoned; see each kit docs/rule-ids.md Renamed table.

cperf (cp-alloc-hot–cp-printf-hot / cp-strlen-in-cond / cp-strcat-hot)

Fixtures use descriptive names (not cp-alloc-hot.c). Defaults from docs/evidence-policy.md / --preset app.

rulebad fixturegood / negativeevidence md+jsonlseverity defaultnotes
cp-alloc-hotbad/cp-alloc-hot_malloc_loop.cyes (arena_hoisted.c, …)yes evidence/cp-alloc-hot.*errorMeasured gate present
cp-realloc-grow-onebad/cp-realloc-grow-one_realloc_grow.cyes (capacity_doubling.c, realloc_wrapper.c)yeserrorMeasured ~12.6× realloc-grow vs doubling
cp-printf-hotbad/cp-printf-hot_printf_loop.cyes (dump_*, ifdef_dump_*, treeview_*, …)yesoffHot ~4.8× unbuf/buf; #if 0 ~1× → stays off
cp-strlen-in-condbad/cp-strlen-in-cond_strlen_cond.cyes (cp-strlen-in-cond_strlen_hoisted.c, …)none yethintNo wall-clock bench; corpus TPs only
cp-strcat-hotbad/cp-strcat-hot_strcat_loop.cyes (cp-strcat-hot_strcat_once.c)none yetoffG3 demote (CLI/path OK-idiom); no wall-clock bench
cp-sprintf-hotbad/cp-sprintf-hot_sprintf_loop.cyesjsonlhintmicrobench ~13.9× on one shape; stay hint; not corpus-triaged
cp-fopen-hotbad/cp-fopen-hot_fopen_loop.cyesjsonlhintmicrobench ~423.4× on one shape; stay hint; not corpus-triaged
cp-gettime-hotbad/cp-gettime-hot_gettime_loop.cyesjsonlhintmicrobench ~33.2× on one shape; stay hint; not corpus-triaged
cp-wide-bool-flagsbad/cp-wide-bool-flags_ints.cyes (cp-wide-bool-flags_bits.c)jsonlhintmicrobench ~19.1× on one shape; stay hint; not corpus-triaged

jsperf (slug ids)

Descriptive fixture names. Defaults: --preset app (jp-console-hot=off).

rulebad fixturegood / negativeevidence md+jsonlseverity defaultnotes
jp-alloc-hotbad/jp-alloc-hot_new_in_loop.js, jp-alloc-hot_push_object.jsyes (prealloc.js, jp-alloc-hot_reuse_buffer.js, …)yesoff (app)~19× / ~6.4× wall-clock (alloc/GC); G3 OK-idiom demote
jp-console-hotbad/jp-console-hot_console_loop.jsyes (jp-console-hot_console_outside_loop.js)yesoff (app) / hint~1328× if stdout discarded; env-dependent → not CI error
jp-delete-shapebad/jp-delete-shape_delete.jsyes (no_delete.js, …)yes evidence/jp-delete-shape.*off (app)G3 OK-idiom demote
jp-delete-array-holebad/jp-delete-array-hole_holey_delete.jsyes (no_holey_delete.js, …)yes evidence/jp-delete-array-hole.*errorMeasured
jp-string-plus-in-loopremoved (fixtures under evidence/_removed/fixtures/)tombstonejsonl under _removed/removedpush+join was not ~2× on matched shapes
jp-map-filter-chainbad/jp-map-filter-chain_map_filter_chain.jsyes (jp-map-filter-chain_single_map.js, comment fixture)yeshint35000 rows ~4.6×/9.8×; 3-row filter+map 1.28×; stay hint
jp-regex-ctor-hotbad/jp-regex-ctor-hot_ctor_loop.jsgood/jp-regex-ctor-hot_ctor_once.js, pattern-variesjsonlhintNode 26 fixed pattern ~4.4×; loop binding not reported
jp-json-hotbad/jp-json-hot_json_loop.jsgood/jp-json-hot_json_once.js, text-variesjsonlhintNode 26 unchanged text ~140×; rows[i] not reported
jp-dom-query-hotbad/jp-dom-query-hot_query_loop.jsgood/jp-dom-query-hot_query_once.js, selector-variesjsonlhintNode 26 tiny linkedom document ~16×; loop binding not reported
jp-intl-datetimeformat-hotbad/jp-intl-datetimeformat-hot_format_loop.jsgood/jp-intl-datetimeformat-hot_format_once.js, locale-variesjsonlhintNode 26 ~36×; loop binding not reported
jp-readfile-sync-hotbad/jp-readfile-sync-hot_read_loop.jsgood/jp-readfile-sync-hot_read_once.js, for-of header, path-variesjsonlhintbody only; Node 26 ~114× when the path stays the same
jp-clock-hotbad/jp-clock-hot_clock_loop.jsgood/jp-clock-hot_clock_once.js, await loop, nested fn/arrowjsonlhinttight loop ~26×/~19×; await loops not reported; nested fn bodies skipped
jp-query-all-starbad/jp-query-all-star_star_query.js, jp-query-all-star_in_template.jsgood/jp-query-all-star_narrow.js, template narrownone yethintfull-tree *; message does not say cache that node; sees template scripts
jp-execjs-in-timerbad/jp-execjs-in-timer_interval.jsgood/jp-execjs-in-timer_once.jsnone yethintbuilt script in setInterval/setTimeout; install once + short drain is clean
jp-clone-per-eventbad/jp-clone-per-event_structured.js, jp-clone-per-event_json_roundtrip.jsgood/jp-clone-per-event_field.js, unrelated clonenone yethintonly event-like args (e/event/…)

zperf (zp-alloc-hot–zp-fixed-size-alloc-hot)

Paired fixtures for all 28. Evidence under packages/zperf/evidence/ (Zig 0.17.0 -Ofast, 2026-10-21). Policy: packages/zperf/docs/evidence-policy.md. CLI still fails on any finding; candidate error = policy escalate when presets land.

rulebadgoodevidencerules.zig sevnotes
zp-alloc-hotyesyesyeswarning~1.4× GPA vs arena — modest; keep warning
zp-append-without-reserveyesyesyesinfo~2.1× append reserve
zp-page-allocator-smallyesyesyeswarning~341× page vs GPA — candidate error
zp-debug-allocatoryesyesN/Awarningstatic-only (mode switch)
zp-large-struct-by-valueyesyesinconclusiveinfoReleaseFast elided microbench
zp-print-hotyesyesyeswarning~6e4× print vs quiet — env I/O, not escalate
zp-unbuffered-ioyesyesyeswarning~49× empty vs 4KiB — candidate error
zp-missing-freeyesyesN/Awarningcorrectness (leak)
zp-extern-struct-paddingyesyesyeswarning~1.2× padded walk — modest
zp-broad-runtime-safetyyesyespendingwarningneed ReleaseSafe measure
zp-packable-boolsyesyespendinginfodensity
zp-usize-index-fieldyesyespendinginfodensity
zp-aos-single-fieldyesyesyeshint~6.6× AoS vs SoA
zp-catch-unreachable-allocyesyesN/Awarningcorrectness (UB)
zp-oversized-enum-tagyesyesN/Ainfostatic size/ABI
zp-optional-scalar-fieldyesyespendinginfodensity
zp-bool-arrayyesyesyesinfo~30× bool[] vs bitset
zp-static-string-mapyesyesyesinfo~2.5× StaticStringMap
zp-runtime-div-hotyesyesyeshint~12× mod vs mask
zp-queue-ordered-removeyesyesyeswarning~466× orderedRemove vs ring — candidate error
zp-shift-on-readyesyesyeswarning~17× copyForwards vs cursor — candidate error
zp-per-packet-allocyesyesyes (shares zp-alloc-hot)warninghot-path alloc; same ~1.4×
zp-invariant-float-divyesyesyeshint~2.0× float div vs recip
zp-map-put-without-ensureyesyesyesinfo~2.8× map ensure
zp-catch-unreachable-ioyesyesN/Awarningcorrectness
zp-arena-reset-free-allyesyesyeswarning~3.2× free_all vs retain
zp-create-destroy-hotyesyesyeswarning~11× create/destroy vs pool — candidate error
zp-fixed-size-alloc-hotyesyesyeswarning~8.5× fixed alloc vs pool — candidate error

jvmperf (jp-boxed-primitive-collection–jp-non-static-field-updater) — summary

IDs are jvmperf jp-* slugs, not jsperf. Fixtures: mostly bad/<slug>.* + .kt with matching good/; Kotlin-only for several collection/boxing rules; jp-boxed-stream / jp-non-static-field-updater Java-only. vt-unsafe-threadlocal-pool is guide-only under jvmperf-lint/fixtures/guide/ (not shipped).

rulebad fixturegood / negativeevidence md+jsonlseverity defaultnotes
jp-boxed-primitive-collectionyes (java+kt)yesyeserror~5.96× STATIC-VS-HOTSPOT
jp-string-concat-hotyes (java+kt)yesyeserrorJ23 ~14.2×
jp-regex-hotyes (java+kt)yesyeshintJ26 ~1.36×
jp-format-hotyes (java+kt)yesyeserror~17×
jp-unpresized-collectionyes (java+kt)yesyeshintPARTIAL ~1.6×
jp-boxed-streamyes (java)yesyeserrorJ32 ~149×
jp-exception-control-flowyes (java+kt)yesyeserrorJ32 ~64×
jp-legacy-synchronized-type (removed)yes (java+kt, archived)yesyes (~1.08×)—measured-no-win; tombstone _removed/
jp-many-boolean-fields (removed)yes (java+kt, archived)yesyes (1.0×)—COH no footprint win; tombstone _removed/
cx-sstream-in-loop (removed)archivedarchived1.24× at -O2—string-stream reuse; tombstone
pp-regex-compile-in-loop (removed)archivedarchivedunder 3×—CPython caches re.compile; tombstone
rs-map-new-in-loopbad/rs-map-new-in-loop_map_loop.rsyesyeshinttwo quiet rustc 1.99 runs about 1.51× and 1.53×; restored
pp-datetime-format-in-loop (removed)archivedarchivedno hoist—changing input cannot skip the call
gp-time-parse-in-loop (removed)archivedarchivedno hoist—changing input cannot skip the call
rb-date-parse-in-loop (removed)archivedarchivedno hoist—changing input cannot skip the call
jp-enum-key-hash-collectionyes (java+kt)yesyeserrorEnumMap ~2.1×
jp-collection-chainyes (kt)yesyeserrorJDK 27 / Kotlin 2.4.21 ~265×
jp-value-class-boxingyes (kt)yesyeserrorJDK 27 ~4.0× time, ~5× B/op
jp-lambda-to-non-inline-hotyes (kt)yesyeserrorJDK 27 alloc ~244×; time ~0.47×
jp-lazy-default-modeyes (kt)yesmd stub onlyhintpending — situational lazy
jp-data-copy-hotyes (kt)yesyeserrorJDK 27 ~208× time, alloc still ~10001×
jp-android-sparse-arrayyesyesmd stubhintpending ART
jp-log-hotyesyesyeserrorJ32 ~28× (debug off)
jp-sleep-pollingyesyesmd stubhintpending sleep design
jp-finalizeyesyesmd stubhintpending finalize/Cleaner
jp-expensive-alloc-hotyesyesyeshintnegative tiny-pool
jp-hot-heavy-alloc–jp-ui-text-appendyesyesmd stubshintpending ART/device
jp-baos-tobytearray-copyyesyesyeserrorJ32 ~12.8×
jp-hot-payload-copyyesyesyeserrorJ32 ~15.8×
vt-unsafe-threadlocal-poolguide onlyguidemd stub (vt-unsafe-threadlocal-pool.md)—not shipped / guide-first
jp-client-factory-recreateyesyesyeserrorJ32 HttpClient ~5e5×
jp-string-intern-hotyesyesyeserrorJ32 intern ~6.6×
jp-non-static-field-updateryes (java)yesyeshintcreate ~165×; inc ~1.0×

CLI today may still fail on any finding; policy severity is the keep/escalate contract until presets land.



Scaffold evidence contract: until JSONL exists, each scaffold rule MUST have a named pending stub packages/<kit>/evidence/<ID>.md (not only a folder README). That satisfies registry parity without inventing ratios.

goperf (gp-make-hot–gp-defer-hot) — corpus-ready

RuleBad fixtureGood fixtureEvidenceDefaultNotes
gp-make-hotbad/gp-make-hot_make_loop.goyesyesoffG4 ~265× make-each; stay off (G3 OK-idiom)
gp-string-plus-hotbad/gp-string-plus-hot_string_plus.goyesyesoffG4 ~2919× += vs Builder; stay off
gp-fmt-hotbad/gp-fmt-hot_fmt_loop.goyesyesoffG4 ~1.8–2.8× fmt vs strconv; stay off
gp-append-nil-slicebad/gp-append-nil-slice_append_grow.gogood/gp-append-nil-slice_presize.goyeshintG4 ~12.2× append grow vs presize
gp-defer-hotbad/gp-defer-hot_defer_loop.gogood/gp-defer-hot_close_each.go + closureyeshintG4 ~33× defer-in-loop vs close-each
gp-regexp-compile-hotbad/gp-regexp-compile-hot_compile_loop.gogood/gp-regexp-compile-hot_compile_once.gojsonlhintmicrobench ~7.1× on one shape; stay hint; not corpus-triaged
gp-json-marshal-hotbad/gp-json-marshal-hot_marshal_loop.gogood/gp-json-marshal-hot_marshal_once.gojsonlhintmicrobench ~368.4× on one shape; stay hint; not corpus-triaged
gp-reflect-hotbad/gp-reflect-hot_reflect_loop.gogood/gp-reflect-hot_reflect_once.gojsonlhintmicrobench ~1×, no meaningful cost; stay hint

pyperf (pp-str-plus-hot–pp-print-hot) — corpus-ready

RuleBad fixtureGood fixtureEvidenceDefaultNotes
pp-str-plus-hotbad/pp-str-plus-hot_str_plus.pyyesyesoffG4 ~5.5× += vs join; stay off
pp-list-plus-rebindbad/pp-list-plus-rebind_list_plus.pyyesyeshintG4 ~1117× list+ rebind; stay hint
pp-print-hotbad/pp-print-hot_print_loop.pyyesyesoffG4 ~3.4× print loop; stay off
pp-json-hotbad/pp-json-hot_json_loop.pygood/pp-json-hot_json_once.pyjsonlhintmicrobench ~81.6× on one shape; stay hint; not corpus-triaged
pp-deepcopy-hotbad/pp-deepcopy-hot_deepcopy_loop.pygood/pp-deepcopy-hot_deepcopy_once.pyjsonlhintmicrobench ~21.8× on one shape; stay hint; not corpus-triaged
(removed — no slug) re-adhoc in loopbad/pp004_re_adhoc.py (archived)good/pp004_re_compiled.pyyes—tombstone; G4 ~1.35× / warm may reverse

swiftperf (sp-force-unwrap-in-loop–sp-map-joined-chain) — corpus-ready

IDBad fixtureGoodEvidenceDefaultNotes
sp-force-unwrap-in-loopforce_loopyesblockedoffG4 blocked — no swiftc on Linux
sp-string-plus-in-loopstring_plusyesblockedoffG4 blocked — no Swift toolchain
sp-print-hotprint_loopyesblockedoffG4 blocked — no Swift toolchain
sp-array-no-reserveappend_no_reserveyesblockedhintG4 blocked — no Swift toolchain
sp-map-joined-chainmap_joinedyesblockedhintG4 blocked — no Swift toolchain
sp-dateformatter-hotsp-dateformatter-hot_formatter_loop.swiftyesjsonlhintmicrobench ~29.8× on one shape; stay hint; not corpus-triaged
sp-json-decode-hotsp-json-decode-hot_decode_loop.swiftyesjsonlhintmicrobench ~1958.0× on one shape; stay hint; not corpus-triaged
sp-regex-hotsp-regex-hot_regex_loop.swiftyesjsonlhintmicrobench ~16.4× on one shape; stay hint; not corpus-triaged

r4 n=32 TP 65.6% FP+DOC+SKIP 0% → corpus-ready: yes (text-lint fallback; SPM when Swift present). G4 2026-10-22: blocked (no fake JSONL). The three 2026-10-23 hints are outside that verdict.

arktsperf (at-alloc-hot–at-json-hot) — corpus-ready

IDBad fixtureGoodEvidenceDefaultNotes
at-alloc-hotnew_loopyesyes (Node proxy)offG4 ~33× new vs reuse; stay off
at-object-deletedeleteyesyes (inconclusive)offG4 ~1.0× (fill-dominated); isolated delete modest; stay off
at-console-hotconsole_loopyesyes (Node proxy)offG4 ~208×; stay off
at-includes-hotincludes_loopyes (+ at-includes-hot_string_lut)yes (Node proxy)hintG4 29× includes→Set; String.indexOf→LUT (Map1×); stay hint
at-json-hotjson_loopyesyes (Node proxy)hintG4 ~2.2× parse / ~1.7× stringify; stay hint

r3 n=56 TP 66.1% FP+DOC+SKIP 0% → corpus-ready: yes. G4 is Node/V8 proxy, not ArkTS VM — no escalate to error.

cppperf (cx-string-append-unreserved) — corpus-ready

Active rule: cx-string-append-unreserved (default hint). Vector-push / iostream / .at() rules removed (tombstones). Dedicated C++17 (≠ cperf).

rulebad fixturegood / negativeevidence md+jsonlseverity defaultnotes
(removed — no slug) vector push without reservebad/cx001_push_loop.cpp (archived)yesyes—tombstone; G4 ~1.58× @-O2
cx-string-append-unreservedbad/cx-string-append-unreserved_string_plus.cppyes (cx-string-append-unreserved_append_reserve.cpp)yeshintG4 1.09× char @-O2; chunk1.8×; stay hint
cx-regex-ctor-hotbad/cx-regex-ctor-hot_regex_loop.cppgood/cx-regex-ctor-hot_regex_once.cppjsonlhintmicrobench ~1.55×, small; stay hint
cx-endl-hotbad/cx-endl-hot_endl_loop.cppgood/cx-endl-hot_newline.cppjsonlhintmicrobench ~1×, no meaningful cost; stay hint
(removed — no slug) iostream in loopbad/cx003_iostream_loop.cpp (archived)yesyes—tombstone; G4 ~1.01×
(removed — no slug) .at() in loopbad/cx004_at_loop.cpp (archived)yesyes—tombstone; G4 ~0.85× reverse @-O2

csharpperf (cs-list-add-no-capacity–cs-regex-hot) — corpus-ready

cs-list-add-no-capacity–cs-console-hot default off after G3. cs-regex-hot default hint. G4 on .NET 8.0.426 (2026-10-22); no severity escalate.

rulebad fixturegood / negativeevidence md+jsonlseverity defaultnotes
cs-list-add-no-capacitybad/cs-list-add-no-capacity_add_loop.csyes (cs-list-add-no-capacity_capacity.cs)yesoffG4 ~13× List capacity; stay off
cs-string-plus-hotbad/cs-string-plus-hot_string_plus.csyes (cs-string-plus-hot_builder.cs)yesoffG4 ~3758× string+=; stay off
cs-console-hotbad/cs-console-hot_console_loop.csyes (cs-console-hot_console_outside.cs)yesoffG4 ~6× Console null; stay off
cs-regex-hotbad/cs-regex-hot_regex_loop.csyes (cs-regex-hot_compiled_regex.cs)yeshintG4 ~2.6× IsMatch vs Compiled; stay hint
cs-linq-materialize-hotbad/cs-linq-materialize-hot_tolist_loop.csgood/cs-linq-materialize-hot_tolist_once.csjsonlhint.NET 10 ~38.9× on one shape; stay hint; not corpus-triaged
cs-format-hotbad/cs-format-hot_format_loop.csgood/cs-format-hot_format_once.csjsonlhint.NET 10 ~5.0× on one shape; stay hint; not corpus-triaged

phpperf (ph-string-dot-hot–ph-echo-hot) — corpus-ready

ph-array-merge-rebind default error after G4 (ph-array-merge-rebind.md+jsonl). ph-string-dot-hot default off (G3 OK-idiom-heavy) and ph-echo-hot hint; both have measured JSONL.

rulebad fixturegood / negativeevidence md+jsonlseverity defaultnotes
ph-string-dot-hotbad/ph-string-dot-hot_str_dot.phpyes (ph-string-dot-hot_implode.php)yesoffG4 ~3.3× .= vs implode; stay off
ph-array-merge-rebindbad/ph-array-merge-rebind_array_merge.phpyes (ph-array-merge-rebind_push.php)yeserrorarray_merge rebind; G4 2026-10-22
ph-echo-hotbad/ph-echo-hot_echo_loop.phpyes (ph-echo-hot_echo_outside.php)yeshintG4 ~4.4× echo each; stay hint

rubyperf (rb-string-plus-hot–rb-file-read-hot) — corpus-ready

rb-string-plus-hot–rb-puts-hot default off after G3. rb-hash-merge-in-loop was removed on 2026-10-23: the literal build was slower than merge and allocated more.

rulebad fixturegood / negativeevidence md+jsonlseverity defaultnotes
rb-string-plus-hotbad/rb-string-plus-hot_str_plus.rbyesyesoffG4 ~32× += vs <<; stay off
rb-array-plus-rebindbad/rb-array-plus-rebind_array_plus.rbyesyesoffG4 ~181× array+ rebind; stay off
rb-puts-hotbad/rb-puts-hot_puts_loop.rbyesyesoffG4 ~5.1× puts each; stay off
rb-hash-merge-in-loop (removed)archivedarchivedtombstone—Ruby 4.0.8 literal slower than merge (~0.78×) and ~2× objects
rb-regexp-new-hotbad/rb-regexp-new-hot_regexp_loop.rbgood/rb-regexp-new-hot_regexp_once.rbjsonlhintmicrobench ~7.7× on one shape; stay hint; not corpus-triaged
rb-json-hotbad/rb-json-hot_json_loop.rbgood/rb-json-hot_json_once.rbjsonlhintmicrobench ~10.5× on one shape; stay hint; not corpus-triaged

rustperf (rs-alloc-hot–rs-collect-vec-hot) — corpus-ready (r4)

rs-vec-no-capacity/rs-collect-vec-hot redesign 2026-10-22. r4 clap residuals 6×TP / FP+DOC+SKIP 0% → corpus-ready: yes. rs-format-rebind-hot format! rebind → error (~99×); rs-string-plus-in-loop/rs-vec-no-capacity/rs-collect-vec-hot → hint; rs-alloc-hot → off (G4 measured, stayed off); rs-println-hot → hint (measured).

rulebad fixturegood / negativeevidence md+jsonlseverity defaultnotes
rs-alloc-hotbad/rs-alloc-hot_clone_loop.rsyes (rs-alloc-hot_with_capacity.rs)yesoffalloc/clone; G4 ~2.7× Vec / ~1.1× clone — stay off
rs-string-plus-in-loopbad/rs-string-plus-in-loop_string_plus.rsyes (rs-string-plus-in-loop_write.rs, rs-string-plus-in-loop_tiny_sep.rs)yeshint+= / push_str only; ~1× amortized
rs-println-hotbad/rs-println-hot_println_loop.rsyes (rs-println-hot_println_outside.rs)yeshintG4 ~12.6× writeln each vs buffer; stay hint
rs-format-rebind-hotbad/rs-format-rebind-hot_format_rebind.rsyes (rs-format-rebind-hot_write.rs, rs-format-rebind-hot_let_format.rs, rs-format-rebind-hot_brace_wrap.rs)yes (aliased G4)errorformat! rebind reuse; ~99× vs write!
rs-vec-no-capacitybad/rs-vec-no-capacity_vec_new_push.rsyes (rs-vec-no-capacity_with_capacity.rs, rs-vec-no-capacity_cfg_test.rs)yeshintG4 ~1.0× large / ~2.1× small builders; stay hint
rs-collect-vec-hotbad/rs-collect-vec-hot_collect_in_loop.rsyes (rs-collect-vec-hot_count_no_collect.rs)yeshintG4 ~1.8× collect vs count; stay hint
rs-regex-new-hotbad/rs-regex-new-hot_regex_loop.rsgood/rs-regex-new-hot_regex_once.rsmd onlyhintpending measure; not corpus-triaged

kotlinperf (kt-list-add-hot–kt-println-hot) — corpus-ready

kt-list-add-hot–kt-println-hot default off (G3 OK-idiom). Empty-collection-add rule removed (tombstone). G4 on kotlinc 2.0.21 / JRE 21 (2026-10-22); kit-local kt-* ≠ jvmperf JMH. No escalate.

rulebad fixturegood / negativeevidence md+jsonlseverity defaultnotes
kt-list-add-hotbad/kt-list-add-hot_list_loop.ktyes (kt-list-add-hot_capacity.kt)yesoffG4 ~2.1× empty vs capacity @2e6; stay off
kt-string-plus-hotbad/kt-string-plus-hot_string_plus.ktyes (kt-string-plus-hot_buildString.kt)yesoffG4 ~1170× += vs buildString; stay off
kt-println-hotbad/kt-println-hot_println_loop.ktyes (kt-println-hot_println_outside.kt)yesoffG4 ~99× println; stay off
(removed — no slug) empty list + addbad/kt004_empty_add.kt (archived)yesyes (inconclusive)—tombstone; G4 ~0.84–1.26×

objcperf (oc-nsstring-append-hot–oc-nslog-hot) — corpus-ready

Active: oc-nsstring-append-hot / oc-nslog-hot (default off). Date-formatter, JSON, and regular-expression rules are hint and are not part of the 2026-10-22 corpus verdict. Array-add rules removed (tombstones). G4 on GNUstep (not Apple runtime) 2026-10-22. Distinct from swiftperf. No escalate.

rulebad fixturegood / negativeevidence md+jsonlseverity defaultnotes
(removed — no slug) NSMutableArray addbad/oc001_add_loop.m (archived)yesyes (gnustep-proxy)—tombstone; G4 ~1.18× / dive ~1×
oc-nsstring-append-hotbad/oc-nsstring-append-hot_append_loop.myes (oc-nsstring-append-hot_mutable.m)yes (gnustep)offG4 ~569× append; stay off
oc-nslog-hotbad/oc-nslog-hot_nslog_loop.myes (oc-nslog-hot_nslog_outside.m)yes (fprintf proxy)offG4 ~191×; stay off
oc-dateformatter-hotbad/oc-dateformatter-hot_alloc_loop.myesjsonlhintmicrobench ~30.4× on one shape; stay hint; not corpus-triaged
oc-json-hotbad/oc-json-hot_json_loop.myesjsonlhintmicrobench ~15.8× on one shape; stay hint; not corpus-triaged
oc-regex-hotbad/oc-regex-hot_regex_loop.myesjsonlhintmicrobench ~14.9× on one shape; stay hint; not corpus-triaged
(removed — no slug) empty array + addbad/oc004_empty_add.m (archived)yesyes (gnustep-proxy)—tombstone; G4 ~1.18× / dive ~1×

dartperf (dt-list-add-empty–dt-growable-add-empty) — corpus-ready

dt-list-add-empty–dt-print-hot default off. dt-growable-add-empty default hint. G4 on Dart 3.13.6 (2026-10-22). No escalate.

rulebad fixturegood / negativeevidence md+jsonlseverity defaultnotes
dt-list-add-emptybad/dt-list-add-empty_add_loop.dartyes (dt-list-add-empty_filled.dart)yesoffG4 ~3.1× filled vs empty add; stay off
dt-string-plus-hotbad/dt-string-plus-hot_string_plus.dartyes (dt-string-plus-hot_buffer.dart)yesoffG4 ~247× string+; stay off
dt-print-hotbad/dt-print-hot_print_loop.dartyes (dt-print-hot_print_outside.dart)yesoffG4 ~128× write; stay off
dt-growable-add-emptybad/dt-growable-add-empty_empty_add.dartyes (dt-growable-add-empty_filled.dart)yeshintG4 ~2.4×; stay hint

luaperf (lu-table-insert-hot–lu-print-hot) — corpus-ready

lu-table-insert-hot default off (G3 OK-idiom). lu-string-concat-hot default error after G4 (lu-string-concat-hot.md+jsonl). lu-print-hot G4 evidence present; default stays hint (I/O env-dependent).

rulebad fixturegood / negativeevidence md+jsonlseverity defaultnotes
lu-table-insert-hotbad/lu-table-insert-hot_insert_loop.luayes (lu-table-insert-hot_index.lua)yesoffG4 ~4.7× insert vs index; stay off
lu-string-concat-hotbad/lu-string-concat-hot_concat_loop.luayes (lu-string-concat-hot_concat.lua)yeserrorstring ..; G4 2026-10-22
lu-print-hotbad/lu-print-hot_print_loop.luayes (lu-print-hot_print_outside.lua)yeshintprint in loop; G4 2026-10-22 stays hint

beamperf (be-list-concat-reduce–be-enum-map-filter-chain) — corpus-ready

IDBad fixtureGoodEvidenceDefaultNotes
be-list-concat-reducebad/be-list-concat-reduce_list_plus.exs (+ .erl)yesyeshintG4 ~453× ++ vs cons; stay hint
(removed — no slug) <> string appendbad/be002_string_append.exs (archived)yesyes (mixed)—tombstone; chunk<> wins; tiny/digits may reverse
be-io-puts-hotbad/be-io-puts-hot_io_loop.exsyesyesoffG4 ~3810× IO.puts; stay off
be-map-merge-hotbad/be-map-merge-hot_merge_in_loop.exsyesyeshintG4 ~6.9× Map.merge vs put; KW ~2×; stay hint
be-enum-map-filter-chainbad/be-enum-map-filter-chain_enum_chain.exsyesyeshintG4 ~4.5× map

r3 n=4 TP 75% FP+DOC+SKIP 0% → corpus-ready: yes. G4 be-list-concat-reduce–be-enum-map-filter-chain on OTP 27 / Elixir 1.18 (2026-10-22); no escalate.

nimperf (nm-seq-add-hot–nm-seq-no-capacity) — corpus-ready

RuleBad fixtureGood fixtureEvidenceDefaultNotes
nm-seq-add-hotbad/nm-seq-add-hot_add_loop.nimyespendingoffG3 OK-idiom; G4 blocked — no nim in Debian apt
nm-string-amp-in-loop (removed)archivedarchivedtombstone—Nim 2.2.12 join slower than &= (~0.79×, earlier ~0.69×)
nm-echo-hotbad/nm-echo-hot_echo_loop.nimyespendingoffG4 blocked (no nim toolchain)
nm-seq-no-capacitybad/nm-seq-no-capacity_empty_add.nimgood/nm-seq-no-capacity_ofcap.nimpendinghintG4 blocked (no nim toolchain)

Batch notes

Batch B G4 (2026-10-22): arkts Node-proxy JSONL; beam/csharp/dart/kotlin measured; objc GNUstep (not Apple); swift blocked (no swiftc). Defaults unchanged — no escalate to error this pass.

Gaps called out (honest)

Disk audit 2026-10-21 ~19:31 Asia/Shanghai — every skip / pending / N/A / inconclusive rule now has a named evidence/<ID>.md stub (no invented JSONL).

  1. cperf: bad + good + evidence/cp-*.{md,jsonl} for shipped rules — complete.
  2. jsperf: bad + good + evidence/jp-*.{md,jsonl} for shipped rules — complete.
  3. zperf: paired fixtures for all active rules. Measured JSONL + registered stubs (pending/N/A/inconclusive) — see packages/zperf/docs/evidence-policy.md and packages/zperf/evidence/.
  4. jvmperf fixtures: shipped jp-* bad+good (lang-scoped). vt-unsafe-threadlocal-pool guide-only under fixtures/guide/ + vt-unsafe-threadlocal-pool.md — not shipped.
  5. jvmperf evidence: measured error/hint JSONL for shipped rules with numbers; pending stubs for ART/device and situational rules. See packages/jvmperf/docs/evidence-policy.md.
  6. Still pending measure (honest — need harness/env): zperf density/safety stubs; jvm Android ART device rules.
  7. Naming: c/js good fixtures are descriptive — tests assert suite cleanliness, not one-file-per-rule.
  8. Do not treat corpus dumps or deopt/compilation line counts as regression of meaning.

Cross-language check (2026-10-23)

File-open and clock-sample shapes that already had a cost in C or C++ were timed on the other runnable toolchains. A hint was added only when the ratio was large and the standard library has a reusable handle or a sample that can sit outside the loop. A changing path cannot be hoisted. A loop that needs a fresh timestamp has nothing to hoist. Defaults stay hint.

Checked and not added:

shaperatiowhy no slug
Python time.perf_counter_ns2.866small next to the loop
Ruby Process.clock_gettime2.332small next to the loop
Python getattr1.442no meaningful cost
Ruby send1.938no meaningful cost
JavaScript Reflect.get8.168a few nanoseconds; not the Go FieldByName shape

Name lookup that did clear the bar, still hint: C# GetField plus GetValue about 53× on .NET 10 versus a direct field (cs-field-by-name-hot; a cached FieldInfo.GetValue was still about 42×), Objective-C valueForKey: about 124× (oc-value-for-key-hot), Swift value(forKey:) about 35× (sp-value-for-key-hot).

Zig 0.17 Io.Dir.openFileAbsolute was about 2134× and Io.Clock.awake.now about 42×; both are hints with JSONL. Zig json.parseFromSlice of one unchanged object was about 2683× versus parsing once (zp-json-hot, hint). A first Swift Date() run and a first Objective-C NSDate run were discarded because the after loop was removed by the compiler. A rerun that keeps the result was about 244× and about 769×, and those two hints now have JSONL.

No standard-library object, so no slug and no number: C, C++, and Rust have no JSON parser in the standard library. Zig 0.17's standard library has no regular-expression compiler.

Not measured on this host, so no number and no new slug: JVM and Kotlin (no JDK / kotlinc), PHP, Dart, Lua, Nim, Elixir, ArkTS (do not copy the Node numbers).