Optimize _quickSort with median-of-three pivot selection#6468
Optimize _quickSort with median-of-three pivot selection#6468Sanenelisiwe1975 wants to merge 1 commit intoOpenZeppelin:masterfrom
Conversation
🦋 Changeset detectedLatest commit: d8be4c4 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughThe pull request optimizes the 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
scripts/generate/templates/Arrays.js (1)
67-94:⚠️ Potential issue | 🟠 MajorDuplicate-heavy arrays still keep the linear-recursion worst case.
With the current 2-way partition, values equal to the pivot never move left, so an all-equal sorted array still leaves
pos == beginand recurses onn - 1elements per step. That means the stack-depth failure from#6289is still reachable on a valid sorted input, and the “avoids worst-case O(n²)” wording here is too strong. Please at least recurse on the smaller partition and iterate on the larger one, and consider a 3-way partition if you want duplicate-heavy inputs to avoid the quadratic path as well.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/generate/templates/Arrays.js` around lines 67 - 94, The current 2-way partition in _quickSort leaves pos == begin for arrays with many pivots equal to pivot, causing linear recursion depth; change _quickSort so after partitioning (using pivot, pos, _swap, comp) you always recurse on the smaller side and loop (iterate) to sort the larger side to guarantee O(log n) stack depth (i.e., replace the two recursive calls _quickSort(begin, pos, comp) and _quickSort(pos + 0x20, end, comp) with logic that determines which side is smaller and recurses on that one while updating begin/end for the loop to sort the larger), and optionally consider implementing a 3-way partition (Dutch National Flag) around pivot to handle duplicate-heavy inputs more efficiently.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@scripts/generate/templates/Arrays.js`:
- Around line 67-94: The current 2-way partition in _quickSort leaves pos ==
begin for arrays with many pivots equal to pivot, causing linear recursion
depth; change _quickSort so after partitioning (using pivot, pos, _swap, comp)
you always recurse on the smaller side and loop (iterate) to sort the larger
side to guarantee O(log n) stack depth (i.e., replace the two recursive calls
_quickSort(begin, pos, comp) and _quickSort(pos + 0x20, end, comp) with logic
that determines which side is smaller and recurses on that one while updating
begin/end for the loop to sort the larger), and optionally consider implementing
a 3-way partition (Dutch National Flag) around pivot to handle duplicate-heavy
inputs more efficiently.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 93203aeb-1cb9-4765-8107-22a915117731
📒 Files selected for processing (3)
.changeset/quicksort-median-pivot.mdcontracts/utils/Arrays.solscripts/generate/templates/Arrays.js
5d7ad28 to
ddcb6d2
Compare
Using the first element as pivot degrades to O(n²) on already-sorted inputs, which is the most common real-world case. Switch to median-of- three selection (first, middle, last) to guarantee a balanced split on sorted inputs and avoid worst-case behavior. For arrays of exactly 2 elements the middle and last pointers coincide, so the full three-way selection is skipped and a single comparison sorts them directly.
ddcb6d2 to
d8be4c4
Compare
Using the first element as pivot degrades to O(n²) on already-sorted inputs, which is the most common real-world case. Switch to median-of- three selection (first, middle, last) to guarantee a balanced split on sorted inputs and avoid worst-case behavior.
For arrays of exactly 2 elements the middle and last pointers coincide, so the full three-way selection is skipped and a single comparison sorts them directly.
Fixes #?
Using the first element as pivot degrades to O(n²) on already-sorted inputs, which is the most common real-world case. Switch to median-of-three selection (first, middle, last) to guarantee a balanced split on sorted inputs and avoid worst-case behavior.
For arrays of exactly 2 elements the middle and last pointers coincide, so the full three-way selection is skipped and a single comparison sorts them directly.
Fixes #6289
PR Checklist
npx changeset add)