-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Deque: fix an assertion, speed up and big cleanup #7562
Conversation
Ok it failed again in run::tests::test_inherit_env I think that's a spurious fail.. http://buildbot.rust-lang.org/builders/auto-mac-32-opt/builds/261/steps/test/logs/stdio I want to change the FromIterator impl anyway, so this PR can wait |
Without this, it will hit the assert in fn grow after 32 consecutive add_front.
Add a test that excercises deque growing. Add bench tests for grow, new, add_back, add_front, to expose how slow these functions are.
Fix some issues with the deque being very slow, keep the same vec around instead of constructing a new. Move as few elements as possible, so the self.lo point is not moved after grow. [o o o o o|o o o] hi...^ ^.... lo grows to [. . . . .|o o o o o o o o|. . .] ^.. lo ^.. hi If the deque is append-only, it will result in moving no elements on grow. If the deque is prepend-only, all will be moved each time. The bench tests added show big improvements: Timed using `rust build -O --test extra.rs && ./extra --bench deque` Old version: test deque::tests::bench_add_back ... bench: 4976 ns/iter (+/- 9) test deque::tests::bench_add_front ... bench: 4108 ns/iter (+/- 18) test deque::tests::bench_grow ... bench: 416964 ns/iter (+/- 4197) test deque::tests::bench_new ... bench: 408 ns/iter (+/- 12) With this commit: test deque::tests::bench_add_back ... bench: 12 ns/iter (+/- 0) test deque::tests::bench_add_front ... bench: 16 ns/iter (+/- 0) test deque::tests::bench_grow ... bench: 1515 ns/iter (+/- 30) test deque::tests::bench_new ... bench: 419 ns/iter (+/- 3)
So that deque can be used with IteratorUtil::collect()
Updated. .reserve() remains to do, as well as deciding on method names, smaller representation, and smaller bits like Clone (Clone and Eq now done). |
The deque is determined by vec self.elts.len(), self.nelts, and self.lo, and self.hi is calculated from these. self.hi is just the raw index of element number `self.nelts`
The previous implementation of reverse iterators used modulus (%) of negative indices, which did work but was fragile due to dependency on the divisor.
The deque is split at the marker lo, or logical index 0. Move the shortest part (split by lo) when growing. This way add_front is just as fast as add_back, on average.
We need a reasonably small initial capacity to make Deques faster for the common case.
Ready for merge. Feedback appreciated. |
Fix an assertion in grow when using add_front. Speeds up grow (and the functions that use it) by a lot. We retain the vector instead of creating it anew for each grow. The struct field hi is removed since it is redundant, and all iterators are updated to use a representation closer to the Deque itself, it should make it work even if deque sizes are not powers of two. Deque::with_capacity is also implemented, but .reserve() is not yet done.
…rednet Fix false positive on `filter_next` fixes rust-lang#7561 changelog: Fix false positive on [`filter_next`] when a method does not implement `Iterator`
Fix an assertion in grow when using add_front.
Speeds up grow (and the functions that use it) by a lot. We retain the vector instead of creating it anew for each grow.
The struct field hi is removed since it is redundant, and all iterators are updated to use a representation closer to the Deque itself, it should make it work even if deque sizes are not powers of two.
Deque::with_capacity is also implemented, but .reserve() is not yet done.