Repository navigation
perf-callgrind: JVM vs clojure-rs per-namespace sweep with Bencher - #3
Merged
Merged
Conversation
Per-namespace callgrind sweep over all 1351 test namespaces, both runtimes, Bencher overlay. Key adaptations: SUMMARY-line gate instead of stdout diff, vendored measure recipe with native discovery, new perf-callgrind.yml (ci.yml untouched).
Perf-callgrind sweep for JVM vs clojure-rs (mirrors snippet T1211): per-namespace driver with SUMMARY gate, algoperf measure tool (ported recipe core: valgrind flags, JVM -Xint+EpsilonGC, LD_PRELOAD shim, BMF), perf-callgrind.yml (shard x runtime matrix, Bencher, merge + cross-leg count diff). The first full sweep surfaced 4 test-isolation bugs, fixed here: 3 missing :requires (passed only by ambient load order) and a fail-fast negative-exponent guard (replaces stack-exhaustion dependence; port gap tracked at hhh-pa/clojure#220).
… count-diff jq) - gate job renamed (was test: collides with ci.yml's check name) - JVM leg pins temurin 21.0.13 (deterministic Bencher history) - conservative action majors (v4/v5) - report-compare jq: single-object counts map (verified locally)
- JVM template pins -Duser.language/country (comma-decimal hosts failed 13 namespaces; also stabilizes Ir) - report-compare normalizes :pass for the 2 random-graph namespaces (proven the only varying ones over full 1351x2 sweeps)
CI round 1 evidence (all 8 native shards harvested): - matrix-exponentiation exceeds both legs' budgets (native timed run >1800s on CI; JVM callgrind OOMs the 2g Epsilon heap, reproduced locally). perf/sweep_skips.json excludes it with a reviewed reason (reported, never silent). - shim cross-check compares :test/:fail/:error + :pass>0: the 2 random-graph namespaces tally different assertion counts per run, which flaked the exact comparison. - JVM callgrind OOM now reports the heap hint (was cryptic 'exit 3'). AI-Tool: Muse Code 1.4.14-R7309.1 (Meta Muse Spark)
Round-2 JVM shard 3 failed its callgrind phase with OOM (same exit-3 signature as matrix-exp). Measured locally: 7.4g heap used; the next-heaviest namespace needs 0.67g, so the 2g budget stays and problem-056 joins the skip-list with the measured reason. AI-Tool: Muse Code 1.4.14-R7309.1 (Meta Muse Spark)
2 tasks
|
| Project | clojure-algorithms |
| Branch | perf/1-callgrind |
| Commit | 15824e1 |
| Report | Testbed | Adapter | Status |
|---|---|---|---|
| 1 | ubuntu-latest-clojure-rs | JSON | ✅ No Alerts |
| 2 | ubuntu-latest-jvm | JSON | ✅ No Alerts |
⚠️ WARNING: Truncated view!The full continuous benchmarking report exceeds the maximum length allowed on this platform.
m-hu
marked this pull request as ready for review
November 3, 2026 14:08
michael-h-hu
approved these changes
Nov 3, 2026
michael-h-hu
left a comment
There was a problem hiding this comment.
Session: gentle-menkar. Approving.
Verified on exact HEAD 15824e1: CI run green (after a pre-existing affine-test flake, tracked as #4, cleared on rerun); perf-callgrind run 21/21 success with Bencher uploads proven (338 report URLs in the sampled shard log — ~170 benchmarks x 2 measures as designed). Sweeps: all 16 shards green on both legs. Secrets flow correctly on this same-repo head (the fork-head #2 failure mode is documented there and does not apply). Branch is mergeable, no conflicts. Design reviewed during implementation (SUMMARY gate, count-diff rule, locale pin, threshold policy). Landing approved.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1. Branch:
m-hu:perf/1-callgrind. Spec:docs/1/specification.md(on this branch).Problems
clojure-rscomparisons do not exist here, while the snippet repo has had a
deterministic callgrind sweep with Bencher overlays since T1211.
whole-suite runners: three namespaces use
clojure.set/clojure.java.iowithout requiring them (passing only by ambientload order), and one test depends on stack exhaustion
(
(thrown? Throwable (power 2 -1))with an impl that recursespast zero forever).
Root causes
ci.ymlrunscorrectness only).
measurement) expose load-order dependence:
karger-test,xor-cipher-test, anddisjoint-set-testfail withClassNotFoundException/Syntax error compilingon a freshruntime on both legs (verified JVM fails identically — repo
bugs, not port gaps).
(power 2 -1)never terminates by design; the JVM surfacesthis as a catchable
StackOverflowError, whileclojure-rsaborts the process (SIGABRT, exit 134 — port gap tracked at
Unbounded recursion aborts the process instead of throwing a catchable StackOverflowError clojure#220).
Solutions (why each resolves its problem)
perf/driver.clj: one driver for both legs — require the ns,clojure.test/run-tests, print oneSUMMARY {:test :pass :fail :error}line. Same workload bothlegs; no
System/exit(unemulated natively) — the gate readsstdout.
scripts/ci/go(algoperf): vendored recipe-identical measurecore (valgrind flags, JVM
-Xint+EpsilonGC, LD_PRELOAD shimwith byte-identical C source, BMF shape) with namespace
discovery and the SUMMARY gate instead of full-stdout
comparison (namespaces print nondeterministically).
perf-callgrind.yml: resolve-rs (floatsclojure-rsHEAD) +correctness gate + shard(8) x runtime(2) sweep + per-runtime
merge + JVM-vs-native count-diff gate.
ci.ymluntouched.itself surfaced them): three missing
:requires, onefail-fast negative-exponent guard.
-Duser.language/country): comma-decimalhosts failed 13 namespaces via
format-based assertions andwould perturb Ir counts.
--timeout1800 native /--callgrind-timeout600 + skip-degrade): the slowest namespace needs ~11min on
the native leg, which must not flake the correctness gate.
No regressions
ci.yml,deps.edn,build.cljuntouched; the sweep is a newworkflow file plus additive
perf/+scripts/+docs/.src//test/fixes keep full-suite semantics: therequires are no-ops where already loaded, and the power guard
throws a
Throwableexactly where the test asserts one(whole-suite
clojure -M:teststill the gate's precondition).JVM flags/parsers/BMF are line ports (only discovery, gating,
and naming adapted — all covered by self-tests).
Test Plan
gofmt -lclean,go vet ./...,go test ./...green(
cmd/algoperf,internal/algocore,internal/measure).algoperf measure --self-test: 26/26 checks (SUMMARY,callgrind, shim, EpsilonGC, GNU-time parsers; templates;
leg/skip classifiers).
python3 -c yaml.safe_loadon the workflow + action;git diff --checkclean.--only, 3 namespaces): gate passes, report +BMF + summary outputs verified by shape.
alloc_min=59430912Bon one namespace).
--mergeverified (dedupe + counts + summary render).1351 ok / 0 failed each; cross-leg counts match except
the 2 documented random-graph namespaces (karger,
random-graph-generator), whose
:passvariance isnormalized in
report-compare(proven the only varyingones over the full 1351x2 data).
(no valgrind on this host) — same as T1211.
Housekeeping notes
AI-Tool:trailer convention onthis repo (pushed; not rewritten per policy) — attribution
rides this PR body into the squash instead. New commits on
this branch will carry the trailer.
Admin needed (repo admin)
clojure-algorithms, setBENCHER_API_KEYsecret (Bencher steps fail without it).after first green.
Session: gentle-menkar.
AI-Tool: Muse Code 1.4.14-R7309.1 (Meta Muse Spark)