docs: record the measured #7109 timing in the #7121 changelog fragment - #7125
Conversation
The fragment shipped with no timing claim because the host was too loaded to make one at the time. Measured after merge: `08_string_concat`'s top-level `result += "x"` scaled to 3,000,000 iterations, timed by the program's own `Date.now()` delta over 20 INTERLEAVED pairs, goes 74 ms -> 69 ms (-6.8%) with distributions 72-79 ms vs 68-72 ms. Stated narrowly on purpose. 29 of the 39 workloads in the A/B compile to a byte-identical object, so this is a number about the top-level `+=` self-append idiom the canonical-Str lowering changes, not about the 321 selections #7109 converted. Claude-Session: https://claude.ai/code/session_018ZFER8EEg8K7ez2n6oDrT9
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe changelog adds measured performance results for the module-init canonical-representation change. It records a 3,000,000-iteration improvement from 74 ms to 69 ms and notes output identity across 39 workloads. ChangesModule-init benchmark documentation
Estimated code review effort: 1 (Trivial) | ~2 minutes ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Independent reconciliation of this PR's number, from #7128 — it holds up. Measured on a Raspberry Pi 5 at load 0.16 with
These agree; the spread is almost entirely whether process startup is in the Two additions:
One caveat for anyone reusing that knob: Cost side, reported separately from speed: canonical |
Follow-up to #7121 (#7109). Documentation only — six lines in the changelog
fragment, no code.
#7121 shipped with no timing claim, because the host was at load 15–80 all
session and
08_string_concatat its committed 100 000 iterations runs in under10 ms — below the resolution of its own
Date.now()delta. Saying "we did notmeasure" was the right call then; the measurement has since been made and
belongs in the release notes rather than in a PR comment.
The measurement
08_string_concat's loop, unchanged in shape, scaled to 3 000 000 iterations sothe in-program timer has something to resolve, and timed by that timer (process
startup excluded). 20 interleaved pairs — alternating the two binaries
rather than running 20 of one then 20 of the other, so a drift in host load
cannot be attributed to the change.
4d3ddc9a3(base)−6.8 % median, −5.6 % minimum. The distributions are essentially disjoint,
which is what makes this reportable at load ≈26 — the intra-arm spread is ~9 %
of the median but the arms do not interleave.
The mechanism is visible in the IR and was already in #7121: the top-level
result = result + "x"went from twojs_get_string_pointer_unifiedcalls periteration to Phase 3a's four-arm tag dispatch whose hot arm derives both handles
with a bare
and i64 …, 0xFFFF_FFFF_FFFF.Why it is stated narrowly
29 of the 39 workloads in #7121's object A/B compile to a byte-identical
.o. #7109 converted 321module_init_contextdenials into selections, butmost of those are canonical-i32 promotions that
-O3was already achieving —under the parallel-shadow model every
LocalGetof such a local already readthe i32 slot, so the double slot was dead code.
So this is a number about the top-level
+=self-append idiom, which is theone lowering that changes and survives optimization. It is deliberately not
presented as "#7109 is worth −6.8 %".
Verification
Both binaries built from the same runtime archives (
libperry_runtime.a/libperry_stdlib.aunchanged between the two commits — #7109 touchesperry-codegenonly),PERRY_NO_AUTO_OPTIMIZE=1,--no-cache, and the twolinked binaries confirmed to differ by hash before timing, so this is not an
A/B of one binary against itself.
No code, no test, and no gate changes.
changelog.d/fragments are folded intothe release notes at tag time.
Summary by CodeRabbit