-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: sort/heapsort: Use bottom up heapsort #26031
Comments
Related #25137. Your case might be easier to consider if you have a working prototype with benchmarks showing performance improvements. |
Finished the code, its at the point where it passes all of the tests! I'll clean it up and then put it on gerrit. If I switch sort to just be heapsort, here is what the interface operation counts used to be:
And now they are:
This implies that when Introsort switches to heapsort, this significantly reduces the number of "Less" operations. Though it has a small increase to the number of swaps. This shouldn't be a huge issue for performance though, since when switching to heapsort, it has to have a minimum of 12 elements left, and this should help in the adversarial cases with large numbers of elements. Also I think swaps should be more efficient than less's in many instances -- I can benchmark the time for how the heap sort implementations compare at low numbers of elements if desired. Benchmarking the performance with the standard introsort benchmarks didn't yield any difference, since the standard benchmarks aren't on adversarially chosen data, which is the only time Introsort switches over to using the heap sort implementation. Should I create a new benchmark for how it performs on adversarially chosen data? |
Change https://golang.org/cl/120699 mentions this issue: |
This doesn't need to go through the proposal process if it has no user-visible effect. Brad asked on the CL about the effect on elements that compare equal according to Less but are nonetheless distinguishable in the final output. If the CL really has no effect on that case, then it's just a performance improvement, which is fine. But if it does have a visible effect, then it's probably not worth it, since this is in fallback code that is very rarely used, so its performance doesn't matter much. The fact that the number of Swap calls change suggests that this does have a user-visible effect though. Will close this - review on the CL is fine - but please do NOT change the user-visible ordering for a very rare performance win. |
Sounds good. I will work on debugging why the number of swaps differs, and producing test cases to ensure the ordering doesn't change between this implementation and the current one. |
Currently the golang heapsort implementation uses the standard "siftdown" method, of taking a node, and checking if it is greater than either of its two child nodes. It is faster to use "bottom-up heapsort", as described here https://en.wikipedia.org/wiki/Heapsort#Bottom-up_heapsort, which basically just entails an update to the siftdown method. This will have no outward API changes, since this would just be improving the performance of heapsort, not changing its functionality.
I can implement this, if the proposal is accepted.
The text was updated successfully, but these errors were encountered: