itertools icon indicating copy to clipboard operation
itertools copied to clipboard

itertools::Join is 2X slower than alternative.

Open SteveBattista opened this issue 4 years ago • 3 comments

If you replace: iterable.into_iter().join(sep)

With

iterable.map(AsRef::as_ref)
        .collect::<Vec<_>>()
        .join(sep)

in Itertools::join the performance is 2X faster.

SteveBattista avatar Sep 14 '21 18:09 SteveBattista

Looking at the nightly build, this code is even faster

https://doc.rust-lang.org/std/slice/trait.Join.html

SteveBattista avatar Sep 15 '21 00:09 SteveBattista

i think this may be impossible to fix without changing Self::Item: Display bound into something else or waiting for specialization. Current implementation has no choice but to either use .to_string() (which has some specializations, but at the same will pretty much always box the values unless they are already a String) or write! (which involves dynamic dispatch and going through a lot of fmt internals) - neither of those is a particularly great choice.

I don't have benchmarks to test it, but I'm somewhat curious how .intersperse(sep).collect::<String>() compares in terms of performance.

sugar700 avatar Sep 16 '21 14:09 sugar700

Looking at the code for .intersperse it is much more complicated with two if statements. This is much more complicated than the other code. The other one pulls the if statement out of the loop and then goes though the rest. This would allow for loop optimization and really good pipe-lining in a processor. Looking forward to the test.

SteveBattista avatar Sep 16 '21 15:09 SteveBattista