-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Try to guess a smarter initial capacity in Vec::from_iter #53086
Conversation
r? @kennytm (rust_highfive has picked a reviewer for you, use r? to override) |
This is potentially awesome not only for |
@bors try |
Try to guess a smarter initial capacity in Vec::from_iter > Another possibility is collect could look at the upper bound and be smarter about what capacity to use? ~ #45840 (comment) This is obviously good for hints like `(60, Some(61))` where today we allocate space for 60, then double it should the additional element show up, and it'd be much better to just always allocate 61. More nuanced are hints like `(0, Some(150))`, where today the code uses just the `0`, and thus starts at a capacity of `1`, but with this change will start at `10` instead. This can undeniably increase memory pressure over where it is today, so I expect at least some controversy 🙂 It does use `try_reserve` for the allocation that's more than the lower bound, and thus shouldn't introduce new aborts, at least. And the starting point grows by the root, keeping things fairly contained: even with an hint of `(0, Some(1_000_000_000))` it'll only start at `30_517`. cc @ljedrz cc #48994
☀️ Test successful - status-travis |
@rust-timer build 8612aa2 |
Success: Queued 8612aa2 with parent b47c314, comparison URL. |
Perf is ready. |
Some greens, some reds... I'd say the results are inconclusive 🤔. |
Hmm, for instructions things seem slightly worse overall :( How reliable are the time measurements? It's interesting that webrender-clean-opt is +0.3% for instructions:u, but -1.5% for wall-time. (Another thing that surprised me: max-rss -3.5% for webrender-debug-clean.) I think I'll try something less complicated than the sqrt approximation for the guess; maybe it's just not worth doing that work and making LLVM compile it when people use Vec, even though it's simple integer instructions. (It's less and less helpful the larger the gap anyway.) |
This one only helps lower>0, but by doing so means it's always strictly less than 100% overhead, same as the normal doubling algorithm. And thus doesn't need to do the try_reserve dance or a post-extend cleanup.
fe30b5b
to
aa080f4
Compare
Ok, I've pushed a much simpler change that's only targeted at one side of the problem. Could I get another try+perf run to see whether it's fruitful overall, please? |
@bors try |
⌛ Trying commit aa080f4 with merge 68f12661b56cdca600c5eca7158eb2ba4026e7f3... |
☀️ Test successful - status-travis |
@rust-timer build 68f12661b56cdca600c5eca7158eb2ba4026e7f3 |
Success: Queued 68f12661b56cdca600c5eca7158eb2ba4026e7f3 with parent 26d7b64, comparison URL. |
Perf is ready. |
Hmm, that's again a bit too mixed for me to be happy about. I'll just close this. Anyone interested should feel free to pick this space up again; feel free to use or ignore anything I did in this PR 🙂 |
…rom_iter_48994_2, r=Mark-Simulacrum Improve capacity estimation in Vec::from_iter Iterates on the attempt made in rust-lang#53086. Closes rust-lang#48994
Is
|
@qm3ster Note that this PR is approaching 4 years old, so you might have meant to comment somewhere else. But the reason the (And it's done this way because some iterators only really return a useful hint after looking at an item -- |
This is obviously good for hints like
(60, Some(61))
where today we allocate space for 60, then double it should the additional element show up, and it'd be much better to just always allocate 61.More nuanced are hints like
(0, Some(150))
, where today the code uses just the0
, and thus starts at a capacity of1
, but with this change will start at10
instead.This can undeniably increase memory pressure over where it is today, so I expect at least some controversy 🙂 It does use
try_reserve
for the allocation that's more than the lower bound, and thus shouldn't introduce new aborts, at least. And the starting point grows by the root, keeping things fairly contained: even with an hint of(0, Some(1_000_000_000))
it'll only start at30_517
.cc @ljedrz
cc #48994