-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Iterator::unzip
not zero cost
#72085
Comments
Usage of |
Wait, what? |
In my experiments i got some significantly worse performance by just replacing |
There's no common fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where
FromA: Default + Extend<A>,
FromB: Default + Extend<B>,
Self: Iterator<Item = (A, B)>, However, I'm playing with adding those as optional methods on |
@cuviper The root cause seems to be that |
@leo60228 Another possibility is to add Quick preview doing it my way, before:
After:
|
Closes rust-lang#72085 This consists of the following optimizations: * Adds a `with_capacity` function to `Extend`. This definitely needs more thought if it's going to be stabilized, so I'm not writing an RFC yet. This takes off most of the performance gap. * Optimizes `Vec`'s `Extend` implementation for the case where `size_hint` is 1. This shaves off the remaining performance gap.
I don't believe this is possible. You can't currently specialize on trait generics, only the type the trait is implemented for. |
I don't know why you say that -- if you look at each of the implementations below, they're all Lines 2059 to 2061 in 4802f09
Lines 2090 to 2092 in 4802f09
Line 2129 in 4802f09
So I'm suggesting: impl<T> SpecExtend<T, option::IntoIter<T>> for Vec<T> { |
I tried that and got coherence errors, and I asked on Discord and that was the answer I got. Perhaps it's just a diagnostics issue: I was using |
Hmm, for coherence I'm guessing that it couldn't guarantee whether or not |
This is resolved on the latest nightly, that you for your efforts @cuviper and others! |
In my attempt to move some code to a more functional style I found that the performance regressed significantly. I have narrowed this regression down to the
Iterator::unzip
function.I tried this code:
I expected to see this happen:
I expect these benchmarks to yield the same results, since they both attempt to do the same thing.
Instead, this happened:
The benchmark results are:
From what I can tell from reading the code in the standard library, there are two reasons why the imperative style loop is so much faster. The imperative version uses
Vec::push
instead ofExtend::extend
. Here push is significantly faster. The rest of the difference comes from the fact that the vectors are initialized usingwith_capacity
, whereas the functional variant seems to reallocate. I get the same performance when I change my imperative code to this:Link to the Reddit thread, with a faster but hacky implementation from u/SkiFire13
Meta
I have reproduced this issue on the latest nightly compiler (as of writing):
The text was updated successfully, but these errors were encountered: