Skip to content

perf: reuse scratch buffer in merge sort - #1076

Open
Feralthedogg wants to merge 1 commit into
TheAlgorithms:masterfrom
Feralthedogg:perf/reuse-merge-sort-buffer
Open

Feralthedogg wants to merge 1 commit into
TheAlgorithms:masterfrom
Feralthedogg:perf/reuse-merge-sort-buffer

Conversation

@Feralthedogg

@Feralthedogg Feralthedogg commented Oct 27, 2026 •

Copy link
Copy Markdown

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 >= 2 non-zero-sized elements, the algorithm's temporary-vector allocation requests decrease from 2 * (n - 1) to one. Time complexity remains O(n log n) and peak auxiliary element storage remains O(n). Initializing the reusable buffer adds one n-element copy and keeps the buffer alive for the entire sort.

The existing public signatures and Copy + Ord bounds 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

  • Performance improvement without a public API 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:

Top-down merge sort input Before After
16,384 random u64 values 1.325 ms 0.715 ms
65,536 random u64 values 6.354 ms 3.694 ms
16,384 random 256-byte records 3.022 ms 2.337 ms

Input 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 fmt
  • cargo clippy
  • Full cargo test suite
  • Coverage report workflow
  • CodeQL (Analyze (actions), Analyze (rust), and CodeQL)

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.rs
  • Scoped Clippy check of the production source with the repository's complete lint policy and warnings denied.
  • git diff --check
  • cargo fmt --all -- --check — reports a comment-formatting difference in unchanged src/big_integer/poly1305.rs.
  • cargo clippy --all --all-targets -- -D warnings — reports clippy::needless_bool in unchanged src/ciphers/diffie_hellman.rs:265.
  • cargo test — the process aborts; rerunning the unchanged base with --nocapture --test-threads=1 identifies the assertion failure in data_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.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.90%. Comparing base (fed66cb) to head (3a22602).

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Feralthedogg
Feralthedogg marked this pull request as ready for review October 27, 2026 08:06
@Feralthedogg
Feralthedogg requested a review from imp2002 as a code owner October 27, 2026 08:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants