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

BinaryHeap: Use full sift down in .pop() #30534

Merged
merged 1 commit into from
Jan 11, 2016

Conversation

bluss
Copy link
Member

@bluss bluss commented Dec 23, 2015

BinaryHeap: Use full sift down in .pop()

.sift_down can either choose to compare the element on the way down (and
place it during descent), or to sift down an element fully, then sift
back up to place it.

A previous PR changed .sift_down() to the former behavior, which is much
faster for relatively small heaps and for elements that are cheap to
compare.

A benchmarking run suggested that BinaryHeap::pop() suffers
improportionally from this, and that it should use the second strategy
instead. It's logical since .pop() brings last element from the
heapified vector into index 0, it's very likely that this element will
end up at the bottom again.

Closes #29969
Previous PR #29811

.sift_down can either choose to compare the element on the way down (and
place it during descent), or to sift down an element fully, then sift
back up to place it.

A previous PR changed .sift_down() to the former behavior, which is much
faster for relatively small heaps and for elements that are cheap to
compare.

A benchmarking run suggested that BinaryHeap::pop() suffers
improportionally from this, and that it should use the second strategy
instead. It's logical since .pop() brings last element from the
heapified vector into index 0, it's very likely that this element will
end up at the bottom again.
@rust-highfive
Copy link
Collaborator

r? @alexcrichton

(rust_highfive has picked a reviewer for you, use r? to override)

@bluss
Copy link
Member Author

bluss commented Dec 23, 2015

r? @gankro

@rust-highfive rust-highfive assigned Gankra and unassigned alexcrichton Dec 23, 2015
@Gankra
Copy link
Contributor

Gankra commented Dec 23, 2015

Can you post the numbers, for posterity?

@bluss
Copy link
Member Author

bluss commented Dec 23, 2015

Sure, they're here #29969 (comment) and the direct link is https://gist.github.com/bluss/b179df31a8c683c087c7

I guess they could be interpreted in different ways. It's only testing two different data set sizes, so it's not exactly a well resolved picture of the asymptotics.

@Gankra
Copy link
Contributor

Gankra commented Dec 23, 2015

TL;DR version for time travellers (EDIT: THIS IS BACKWARDS, SEE BELOW):

This reduces benchmark time to be 1/2 to 1/5th for most inputs (small heaps, or cheap comparisons), but for certain inputs makes the benchmark time 2x slower (large heap of expensive comparisons).

@Gankra
Copy link
Contributor

Gankra commented Dec 23, 2015

ARGH.

Ok I had it backwards. This PR is is basically regressing the latest perf of pop ops for small/simple cases in favour of asymptotic gains on large/complex cases. I'm used to integer/float keys for heaps, so this seems backwards!

CC @rust-lang/libs, what do you think we should optimize more for?

@bluss
Copy link
Member Author

bluss commented Dec 23, 2015

cc @dgrunwald

@alexcrichton alexcrichton added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Dec 23, 2015
@Gankra
Copy link
Contributor

Gankra commented Jan 6, 2016

We discussed this at the libs team triage today. There was some wondering if we could dynamically (or statically?) branch on anything to "guess" which strategy would be best. In particular, we could check the size of the heap? The "large heap" case seems like the more pressing one than the "complex key" one.

What do you think?

@bluss
Copy link
Member Author

bluss commented Jan 7, 2016

I'd prefer to merge this change, and put down improved BinaryHeap strategy in the issue list. I'm unlikely to set out for such a major project right now.

@Gankra
Copy link
Contributor

Gankra commented Jan 9, 2016

Ok, that seems reasonable.

@bors r+

@bors
Copy link
Contributor

bors commented Jan 9, 2016

📌 Commit 52883ab has been approved by Gankro

@bors
Copy link
Contributor

bors commented Jan 11, 2016

⌛ Testing commit 52883ab with merge ffdfeeb...

@bors
Copy link
Contributor

bors commented Jan 11, 2016

💔 Test failed - auto-win-gnu-64-nopt-t

@alexcrichton
Copy link
Member

@bors: retry

On Mon, Jan 11, 2016 at 3:24 PM, bors [email protected] wrote:

[image: 💔] Test failed - auto-win-gnu-64-nopt-t
http://buildbot.rust-lang.org/builders/auto-win-gnu-64-nopt-t/builds/2644


Reply to this email directly or view it on GitHub
#30534 (comment).

bors added a commit that referenced this pull request Jan 11, 2016
BinaryHeap: Use full sift down in .pop()

.sift_down can either choose to compare the element on the way down (and
place it during descent), or to sift down an element fully, then sift
back up to place it.

A previous PR changed .sift_down() to the former behavior, which is much
faster for relatively small heaps and for elements that are cheap to
compare.

A benchmarking run suggested that BinaryHeap::pop() suffers
improportionally from this, and that it should use the second strategy
instead. It's logical since .pop() brings last element from the
heapified vector into index 0, it's very likely that this element will
end up at the bottom again.

Closes #29969
Previous PR #29811
@bors
Copy link
Contributor

bors commented Jan 11, 2016

⌛ Testing commit 52883ab with merge 1586005...

@bors bors merged commit 52883ab into rust-lang:master Jan 11, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants