Skip to content
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

Faster heap operations #3933

Merged
merged 3 commits into from
Jan 17, 2016
Merged

Faster heap operations #3933

merged 3 commits into from
Jan 17, 2016

Conversation

andralex
Copy link
Member

I was surprised that building and sorting the heap call percolate which in turn has two stages - going up and going down. To the best of my knowledge, all you need to do to build a heap is to sift elements down (not up). @Xinok could you please comment?

@Xinok
Copy link
Contributor

Xinok commented Jan 15, 2016

I'm afraid this is my handy work. This technique is used in Bottom-Up Heap Sort because it performs nearly half the number of comparisons on average. The upside is that it should be faster when comparisons are expensive but the downside is that it's less cache friendly because it always sifts down all the way to a leaf node before sifting up.

See Pull Request #3479

@tsbockman
Copy link
Contributor

The algorithm could be selected at compile time - use the sift down method for basic types known to have fast comparison operators (integers, floating point, pointers, etc.), but keep the current two-stage method for struct and class instances, to minimize comparisons?

I don't know that it's worth maintaining the extra lines of code, though.

@andralex
Copy link
Member Author

@Xinok OK, I figured there must be some depth to it. So the approach trades comparisons for swaps. What data types did you measure improvements on?

I figure percolate() is sensible when there's not a lot of percolation back up, i.e. when you're actually percolating the extremum. During heap building however, you're percolating an arbitrary element so it makes sense to just go with siftDown. So I kept percolate in heapSort and siftDown in buildHeap. Makes sense?

With this last commit I eliminated one test on the common path in both siftDown and percolate.

@Xinok
Copy link
Contributor

Xinok commented Jan 16, 2016

@andralex I don't remember exactly but most likely an array of integers. However, the benchmarks were for completely sorting the array. Here are some new benchmarks for just building the heap:

~4 million integers.
Sift-Down: 45ms, 7890573 comparisons
Bottom-Up: 54ms, 6917412 comparisons

~1 million strings:
Sift-Down: 93ms, 1911297 comparisons
Bottom-Up: 101ms, 1676076 comparisons

For building the heap, the bottom-up method is slower and doesn't result in a significant reduction of comparisons, so I would say the sift-down method is better. But for sorting, what I said before still applies.

@andralex
Copy link
Member Author

@Xinok Great, thanks! So this pull should be in good order.

@andralex
Copy link
Member Author

this blocks #3934

@9il
Copy link
Member

9il commented Jan 17, 2016

LGTM

@9il
Copy link
Member

9il commented Jan 17, 2016

Auto-merge toggled on

9il added a commit that referenced this pull request Jan 17, 2016
@9il 9il merged commit 7f24ccf into dlang:master Jan 17, 2016
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.

4 participants