-
Notifications
You must be signed in to change notification settings - Fork 150
Use reserve
instead of unchecked math in push
#112
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe worth pointing out in the commit message that reserve()
calls next_power_of_two
, so we don't grow one by one? Anyway looks great :)
`push` currently uses this line to reserve space in the vector: ``` self.grow(cmp::max(cap * 2, 1)) ``` This risks overflowing `usize`. In practice this won't lead to any bugs, because the capacity can't be larger than `isize::MAX` because of invariants upheld in liballoc, but this is not easy to see. Replacing this with `self.reserve(1)` is clearer, easier to reason about safety (because `reserve` uses checked arithmetic), and will make it easier to change the growth strategy in the future. (Currently `reserve(1)` will grow to the next power of 2.) This does not regress any of the `push` benchmarks. Marking `reserve` as inline is necessary to prevent `insert` benchmarks from regressing because of a change in the optimizer's inlining decisions there.
@bors-servo r=emilio |
📌 Commit d2b1900 has been approved by |
Use `reserve` instead of unchecked math in `push` `push` currently uses this line to reserve space in the vector: ``` self.grow(cmp::max(cap * 2, 1)) ``` This risks overflowing `usize`. In practice this can't happen currently, because `cap` can't be larger than `isize::MAX` because of invariants upheld in liballoc, but this is not easy to see. Replacing this with `self.reserve(1)` is clearer, easier to reason about safety (because `reserve` uses checked arithmetic), and will make it easier to change the growth strategy in the future. This does not regress any of the `push` benchmarks. Marking `reserve` as inline is necessary to prevent `insert` benchmarks from regressing because of a change in the optimizer's inlining decisions there. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-smallvec/112) <!-- Reviewable:end -->
☀️ Test successful - status-travis |
Version 0.6.5 Change log: * #115 - add `into_inner` method * #117 - add `from_buf_and_len` and `from_buf_and_len_unchecked` * #118 - optimize `from_slice` * Some code cleanup and testing improvements (#112, #113, #114, #120) cc @llogiq <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-smallvec/121) <!-- Reviewable:end -->
push
currently uses this line to reserve space in the vector:This risks overflowing
usize
. In practice this can't happen currently, becausecap
can't be larger thanisize::MAX
because of invariants upheld in liballoc, but this is not easy to see.Replacing this with
self.reserve(1)
is clearer, easier to reason about safety (becausereserve
uses checked arithmetic), and will make it easier to change the growth strategy in the future.This does not regress any of the
push
benchmarks. Markingreserve
as inline is necessary to preventinsert
benchmarks from regressing because of a change in the optimizer's inlining decisions there.This change is