Open nyurik opened 3 months ago
If anyone wants to try it, run this with cargo bench
:
[dev-dependencies]
criterion = { version = "0.5", features = ["html_reports"] }
[[bench]]
name = "my_benchmark"
harness = false
// benches/my_benchmark.rs
use std::hint::black_box;
use criterion::{criterion_group, criterion_main, Criterion};
#[inline(never)]
pub fn contains(values: &[u8]) -> bool {
values.contains(&10)
}
#[inline(never)]
pub fn has_any(values: &[u8]) -> bool {
values.iter().any(|x| *x == 10)
}
fn criterion_benchmark(c: &mut Criterion) {
let data = vec![20u8; 1000];
let slice = &data[..];
c.bench_function("ref_zero", |b| b.iter(|| contains(black_box(slice))));
c.bench_function("has_any", |b| b.iter(|| has_any(black_box(slice))));
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
This is from specialization for u8
and i8
. See https://github.com/rust-lang/rust/blob/9c01301c52df5d2d7b6fe337707a74e011d68d6f/library/core/src/slice/cmp.rs#L232-L259
@Jarcho ah, thx, i missed the specialization. Thus, it makes perfect sense to do this as a lint for u8 and i8
What it does
Suggest to replace
values.iter().any(|&x| x == 10)
withvalues.contains(&10)
as shown in the example for x beingu8
or ani8
. Contains uses specialization, thus gains 8-10x in performance.The generated assembly is significantly different too (see here).
Advantage
Drawbacks
Example
Could be written as: