Repository navigation
Fix #39: all 27 snippet complexity gaps in one batch - #45
Merged
Merged
Conversation
huffman: binary heap keyed [weight,min-leaf,id], no per-merge re-sort. offline_caching: eviction scans cache once, no per-eviction sort. offline_minimum: binary search for first extract after insert. approx_agreement: sort once per round, hoist trimmed mean. cpu_scheduling: RR ready queue via head index + amortized compaction. distance_vector: on-demand poison-reverse lookup, no N^3 table. pl_resolution: hash-set clause membership instead of linear scan. prufer: sorted-set min-leaf heap for encode and decode. AI-Tool: Muse Code (Meta Muse Spark)
- sort/three_way_quicksort: in-place 3-way quicksort on long-array with explicit stack (smaller side first, O(log n) depth); no 3 filterv copies per level. Avg O(n log n) time kept. - sort/three_way_string_quicksort: same in-place 3-way scheme on an object array with depth-tagged stack entries. - math/approximation/mult_weights: index the flat gain vector directly instead of building a T-by-n gain matrix. O(T n) time kept. - combinatorics/stirling_bell: rolling two-row DP (stirling-row) instead of the full (n+1)x(k+1) table with assoc-in. O(n k) time kept. - compiler/attribute_grammar: Horner fold over the bitstring instead of building an n-node map tree plus O(n) synth recursion. O(n) kept. - data_structure/bst_lca: iterative insert via explicit descent path with bottom-up rebuild; duplicates still go right. O(h) per insert kept. - data_structure/red_black_tree: iterative LLRB insert with explicit path and bottom-up balance fixup (duplicates balance on the way up, as before); root recolored black. O(log n) insert kept. AI-Tool: Muse Code (Meta Muse Spark)
no_prefix_set: O(T log n) sort+segtree -> O(T) linear trie, input-order insert. determining_dna_health: O(T.G) out-scan -> O(T.log G) via per-state prefix health sums plus bisection. banded_alignment: O(nm) full-table scan -> O(nk) band-only enumeration with transient rows. dcel_overlay: O(n^4) per-vertex/per-edge full scans -> single-pass grouping of crossings onto edges and half-edges onto tails. range_tree: O(n^2 log n) take-while scans -> O(n log^2 n) bisection in cascade build and query bounds. segment_stabbing: O(m) per-query rank scan -> O(log m) bisection. AI-Tool: Muse Code (Meta Muse Spark)
- min_cost_max_flow: sorted-vector heap re-sorted per pop -> java.util.PriorityQueue (pop O(h log h) -> O(log h)) - blossom, gale_shapley, second_best_mst, spfa: vector queue copied per dequeue -> PersistentQueue (dequeue O(n) -> O(1) amortized) - dag_shortest_paths: topo vector re-sorted per vertex + O(n) acc-membership scan per edge -> PriorityQueue + seen vector (poll O(h log h)+scan -> O(log h)+O(1)) Validation: 38 hand-built before/after runs (small + adversarial), all byte-identical; e.g. gale n=1500 11.2s->2.3s, spfa star60k 7.4s->0.7s, dag indep20k 4.2s->0.4s, mcmf n=300 10.1s->3.9s, sbmst star250 5.4s->2.0s. AI-Tool: Muse Code (Meta Muse Spark)
This was referenced Nov 3, 2026
Each perf-callgrind run resolves the upstream revision once but all 8 clojure-rs legs still check out + build it from scratch. Cache the release binary in actions/cache keyed by runner OS + resolved SHA so repeat runs skip toolchain, checkout, and build; a .rev marker file fails the leg loudly if a cached binary ever mismatches the revision. AI-Tool: Muse Code (Meta Muse Spark)
PriorityQueue heaps become persistent sorted-sets in atoms (first/disj/conj, still O(log h) per op); array quicksorts become transient vectors with persistent-list stacks (nth/assoc! O(1), smaller-first keeps O(log n) stack); String .charAt becomes nth. Old-vs-new outputs byte-identical on all completing inputs. AI-Tool: Muse Code (Meta Muse Spark)
concurrency cancel-in-progress on non-master refs so a new push replaces the previous commit's sweep; master keeps every run so no landed commit loses its Bencher record. AI-Tool: Muse Code (Meta Muse Spark)
Collaborator
Author
|
Coordination note from issue #40 (harness side; no snippet changes here, nothing duplicated):
AI-Tool: Muse Code (Meta Muse Spark) |
|
| Project | clojure-code-snippet |
| Branch | fix/39-batch-all |
| Commit | 96ac83e |
| 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.
michael-h-hu
approved these changes
Nov 3, 2026
michael-h-hu
left a comment
Collaborator
There was a problem hiding this comment.
Review: PR #45 (fix/39-batch-all @ 96ac83e) — round 1
Focused re-review of the full master...HEAD diff, all 28 files. No blocking findings.
What I checked (correctness of each transformation, not just shape)
- sort (2 files): in-place 3-way partition on transient vectors is a faithful
Dijkstra partition (pivot value captured before swaps; empty ranges skipped on
pop). Smaller-first stack push inthree-way-qsortbounds depth at O(log n).
MSD variant pushes the equal partition with(inc dd)only whenpivot-c != -1. - heaps/queues: huffman binary heap preserves the
[weight, min-leaf, id]total
order (initms0reproduces the old sort keys); mcmf/dagsorted-setheaps keep
stale-entry skipping / zero-indegree-min-first semantics; the four
vector-queue →PersistentQueueswaps preserve FIFO order. - prufer:
firston the neighbor set is safe because a min-leaf always has
degree exactly 1 (single-element set), so min == only element. Leaf-set
maintenance matches the old boolean-vector logic. - stirling_bell: rolling-row recurrences match the old table, including the
signed-first-kind(- i)==-(i1-1)factor. - attribute_grammar:
synth-bitscomputes the same MSB-first value as the old
nested-mapsynth, and removes deep recursion. (Empty bit-string now yields 0
instead of nil — pre-existing edge, arguably a fix.) - dna_health: bisection invariant verified in
build-automaton— genes insert
in gid order viamap-indexed, so every:outis ascending and:pref
differences are exact. - dcel/range_tree/segment_stabbing/offline_minimum: grouping passes and binary
searches reproduce the old scans (cross-multiplied comparator equals ratio order
for positive denominators; bisect indices equal the old take-while counts). - rb_tree/bst_lca: iterative rebuilds apply
balanceat every level including
the duplicate path, matching the recursive versions. - pl_resolution/offline_caching/approx_agreement/mult_weights/cpu_scheduling/
dv_routing/banded/no_prefix_set: set-membership / hoisted-sort / direct-index /
head-index-queue / on-demand-advd/ band-only / trie rewrites all preserve
output semantics (checked tie-breaks, index mappings, and bad-word conditions). - workflow: concurrency group cancels stale branch runs but never master;
cljrs-bincache key is exact-SHA with a.revmarker check that fails loudly
on mismatch. Missing trailing newline in banded_alignment is pre-existing.
Verdict
APPROVE. CI-gated behavior (sweep diff-gates on both runtimes) corroborates the
read-through; the one pending leg (perf-callgrind (5, jvm)) just needs to go
green before landing.
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.
Closes #39 — all 27 snippets whose time/space complexity was worse than
their python twins, in one batch (merges the four area branches; files are
disjoint, merges conflict-free).
Graph (6): heaps + O(1) queues
graph/flow/min_cost_max_flow: Dijkstra heap pop re-sort → O(log h) PQ(n=300: 10.1s → 3.9s).
graph/matching/blossom,graph/matching/gale_shapley,graph/minimum_spanning_tree/second_best_mst,graph/shortest_path/spfa:O(n) vec-dequeue → O(1) PersistentQueue (spfa star n=60000: 7.4s → 0.7s).
graph/shortest_path/dag_shortest_paths: topo re-sort + O(n) scans → PQStrings + geometry (6): tries, bisection, band-only
string_related/trie/no_prefix_set: sort+segtree → persistent trie,O(T log n) → O(T).
string_related/aho_corasick/determining_dna_health: prefix sums +bisect, O(T·G) → O(T·log G) (5.8x).
string_related/banded_alignment/banded_alignment: full table →band-only, O(nm) → O(nk) (4.4x).
computational_geometry/dcel_overlay/solution: O(n⁴) → O(n² log n) (11x).computational_geometry/range_tree/solution: O(n² log n) → O(n log²n) (10x).computational_geometry/segment_stabbing/solution: O(m) → O(log m)/query.Misc time (8): heaps, hash-sets, no re-sorts
dp/huffman(17s → 0.74s),dp/offline_caching,data_structure/offline_minimum,distributed/consensus/approx_agreement,systems/cpu_scheduling(7.42s → 0.55s),systems/distance_vector_routing,search/pl_resolution(19.72s → 2.65s),combinatorics/prufer.Space (7): same time class, smaller footprint
In-place 3-way quicksorts (O(log n) aux),
mult_weightsflat indexing,stirling_bellrolling rows,attribute_grammarHorner fold (3M-bit: OOM→ 0.4s), iterative
bst_lca(sorted-20k: StackOverflow → correct) andred_black_treeinserts.Validation
adversarial inputs via JVM
clojure.main(some with independent pythonoracles); pre-existing quirks preserved byte-identically.
master-identical behavior.
run_tests.py+perf-callgrind on this PR is the full gate.
Supersedes #41, #42, #43, #44.
AI-Tool: Muse Code (Meta Muse Spark)
CI: cache the built clojure-rs binary (from #46)
perf-callgrindresolves the upstream revision once but all 8clojure-rs legs rebuilt it from scratch. The release binary is now
cached by runner OS + resolved SHA (repeat runs skip toolchain,
checkout, and build); a
.revmarker fails the leg loudly on anyrevision mismatch.
Idiomatic rewrite (review feedback)
The four fixes that used Java interop now use idiomatic Clojure with the
same complexity:
PriorityQueue→sorted-setin atoms (mcmf, dag),long-array/object-array+ArrayDeque→ transient vectors +persistent-list stacks (both 3-way quicksorts),
.charAt→nth.Old-vs-new outputs byte-identical on all completing inputs (incl. 2k/3k
sorts, 250-node complete-DAG mcmf, 200-node DAG); two oversized random
mcmf inputs OOM identically before and after.
CI run superseding
concurrencycancels stale branch runs on new pushes; master keepsevery run for Bencher continuity.