Closed
Description
What it does
It suggests the user to change std::iter::repeat(string).take(n).collect::<String>()
to string.repeat(n)
. It should work without the String
type argument to collect
too and clippy has to find out based on context whether it does collect to a String
.
Additionally, when the argument to std::iter::repeat
is a constant char like 'a'
it should suggest to change that to "a".repeat(n)
. I said only constant chars because I'm not sure how well it will work if it does that for variable chars as well.
Categories (optional)
- Kind:
clippy::perf
use criterion::{criterion_group, criterion_main, Criterion};
fn repeat1(count: usize) -> String {
std::iter::repeat("a").take(count).collect()
}
fn repeat2(count: usize) -> String {
"a".repeat(count)
}
fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("std::iter::repeat", |b| b.iter(|| repeat1(100)));
c.bench_function("str::repeat", |b| b.iter(|| repeat2(100)));
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
std::iter::repeat time: [433.62 ns 434.36 ns 435.09 ns]
Found 10 outliers among 100 measurements (10.00%)
4 (4.00%) low mild
5 (5.00%) high mild
1 (1.00%) high severe
str::repeat time: [52.540 ns 52.658 ns 52.857 ns]
Found 3 outliers among 100 measurements (3.00%)
1 (1.00%) high mild
2 (2.00%) high severe
It's faster and generates a lot less instructions, in the char
case too.
It's also easier to read.
Drawbacks
None.
Example
std::iter::repeat("hello").take(10).collect::<String>();
std::iter::repeat('x').take(10).collect::<String>();
Could be written as:
"hello".repeat(10);
"x".repeat(10);
See also: rust-lang/rust#85538.