Skip to content

Instantly share code, notes, and snippets.

@green-s
Last active December 13, 2021 07:20
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save green-s/fbd0d374b290781ac9b3f8ff03e3245d to your computer and use it in GitHub Desktop.
Save green-s/fbd0d374b290781ac9b3f8ff03e3245d to your computer and use it in GitHub Desktop.
#![feature(test)]
extern crate test;
extern crate itertools;
use test::Bencher;
use itertools::Itertools;
fn strings_vec() -> Vec<String> {
vec![String::from("again"); 512]
}
#[bench]
fn consume_collect_join(b: &mut Bencher) {
b.iter(|| {
strings_vec()
.into_iter()
.collect::<Vec<String>>()
.join(" and ")
});
}
#[bench]
fn consume_itertools_join(b: &mut Bencher) {
b.iter(|| strings_vec().into_iter().join(" and "));
}
#[bench]
fn borrow_collect_join(b: &mut Bencher) {
let strings = strings_vec();
b.iter(|| {
strings
.iter()
.map(|s| &**s)
.collect::<Vec<&str>>()
.join(" and ")
});
}
#[bench]
fn borrow_itertools_join(b: &mut Bencher) {
let strings = strings_vec();
b.iter(|| strings.iter().join(" and "));
}
// Results:
//
// test borrow_collect_join ... bench: 24,071 ns/iter (+/- 11,873)
// test borrow_itertools_join ... bench: 41,002 ns/iter (+/- 6,126)
// test consume_collect_join ... bench: 63,260 ns/iter (+/- 18,295)
// test consume_itertools_join ... bench: 82,640 ns/iter (+/- 30,842)
@murlakatamenka
Copy link

If you'd like to bench it yourself:

  1. Make a new lib:
cargo new --lib join
  1. Paste gist content to src/lib.rs

  2. Use nigthly to bench it:

rustup override set nightly
cargo bench

My results on Rust nightly 1.39

test borrow_collect_join    ... bench:       3,391 ns/iter (+/- 124)
test borrow_itertools_join  ... bench:      14,587 ns/iter (+/- 957)
test consume_collect_join   ... bench:      23,930 ns/iter (+/- 762)
test consume_itertools_join ... bench:      40,658 ns/iter (+/- 1,132)

Conclusion

Use collect + join: faster and no dependencies.

@da-x
Copy link

da-x commented Dec 13, 2021

perf shows the consume benches calls malloc heavily whereas the borrow cases don't. Probable itertools explanation in rust-itertools/itertools#577 . I don't have a reference for the core lib case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment