Repository navigation
perf: reuse scratch buffer in merge sort - #1076
Open
Feralthedogg wants to merge 1 commit into
Open
Feralthedogg wants to merge 1 commit into
Feralthedogg wants to merge 1 commit into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1076 +/- ##
=======================================
Coverage 95.89% 95.90%
=======================================
Files 396 396
Lines 30441 30498 +57
=======================================
+ Hits 29192 29249 +57
Misses 1249 1249 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Feralthedogg
marked this pull request as ready for review
October 27, 2026 08:06
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.
Description
Both merge sort implementations allocate two temporary vectors on every merge. Allocate one scratch buffer at the start of each non-trivial sort and reuse it for every merge instead.
For
n >= 2non-zero-sized elements, the algorithm's temporary-vector allocation requests decrease from2 * (n - 1)to one. Time complexity remainsO(n log n)and peak auxiliary element storage remainsO(n). Initializing the reusable buffer adds onen-element copy and keeps the buffer alive for the entire sort.The existing public signatures and
Copy + Ordbounds are preserved. Equal elements are still selected from the right half first, so this change also preserves the existing unstable ordering.Add regression tests that compare complete results against the standard sort for all 9,841 ternary arrays of lengths 0 through 8, exercise merge boundaries around powers of two, and check equal-element identity order using borrowed references.
Type of change
Measurements
A separate standard-library-only harness compared the unchanged base implementation with the exact production functions in this patch. On Apple M4 with Rust 1.95.0 and the default release profile, the median of nine paired samples was:
u64valuesu64valuesInput preparation and correctness checks were outside timing; allocations and frees inside the sort were included. Execution order alternated between samples. These are local synthetic measurements, not production latency guarantees. Empty and single-element inputs were a few nanoseconds slower in the harness. Allocation counts above are structural analysis, not allocator instrumentation.
Validation
GitHub CI
All seven checks passed on commit
3a22602982a896c93df71ce67d2b9ae1ce741197:cargo fmtcargo clippycargo testsuiteAnalyze (actions),Analyze (rust), andCodeQL)Additional local nightly checks
Checked with
nightly-2026-10-27(rustc 1.101.0-nightly (16d1ffac1 2026-10-26)):cargo test sorting::merge_sort::tests— 15 passed; the exhaustive test completed below 300 ms.rustfmt --edition 2021 --check src/sorting/merge_sort.rsgit diff --checkcargo fmt --all -- --check— reports a comment-formatting difference in unchangedsrc/big_integer/poly1305.rs.cargo clippy --all --all-targets -- -D warnings— reportsclippy::needless_boolin unchangedsrc/ciphers/diffie_hellman.rs:265.cargo test— the process aborts; rerunning the unchanged base with--nocapture --test-threads=1identifies the assertion failure indata_structures::hash_table::tests::test_multiple_inserts_and_searches.The full-suite test failure and Clippy diagnostic were reproduced on the unchanged base commit
fed66cb0c74c4a939ec5163648458a8c2b46fd4c. The formatting diagnostic is also in an unchanged file. These additional local nightly results are retained for transparency; the GitHub CI jobs for this PR all pass. The change is ready for review.