mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-19 02:57:33 +00:00
![]() Change `GetManyMutError` to match T-libs-api decision That is, differentiate between out-of-bounds and overlapping indices, and remove the generic parameter `N`. I also exported `GetManyMutError` from `alloc` (and `std`), which was apparently forgotten. Changing the error to carry additional details means LLVM no longer generates separate short-circuiting branches for the checks, instead it generates one branch at the end. I therefore changed the code to use early returns to make LLVM generate jumps. Benchmark results between the approaches are somewhat mixed, but I chose this approach because it is significantly faster with ranges and also faster with `unwrap()`. Benchmark (`jumps` refer to short-circuiting, `acc` is not short-circuiting): ```rust use criterion::{black_box, criterion_group, criterion_main, Criterion}; use my_crate::{get_many_check_valid_acc, get_many_check_valid_jumps, GetManyMutError}; mod externs { #[unsafe(no_mangle)] fn foo() {} #[unsafe(no_mangle)] fn bar() {} #[unsafe(no_mangle)] fn baz() {} } unsafe extern "C" { safe fn foo(); safe fn bar(); safe fn baz(); } fn bench_method(c: &mut Criterion) { c.bench_function("jumps two usize", |b| { b.iter(|| get_many_check_valid_jumps(&[black_box(1), black_box(5)], black_box(10))) }); c.bench_function("jumps two usize unwrap", |b| { b.iter(|| get_many_check_valid_jumps(&[black_box(1), black_box(5)], black_box(10)).unwrap()) }); c.bench_function("jumps two usize ok", |b| { b.iter(|| get_many_check_valid_jumps(&[black_box(1), black_box(5)], black_box(10)).ok()) }); c.bench_function("jumps three usize", |b| { b.iter(|| { get_many_check_valid_jumps(&[black_box(1), black_box(5), black_box(7)], black_box(10)) }) }); c.bench_function("jumps three usize match", |b| { b.iter(|| { match get_many_check_valid_jumps( &[black_box(1), black_box(5), black_box(7)], black_box(10), ) { Err(GetManyMutError::IndexOutOfBounds) => foo(), Err(GetManyMutError::OverlappingIndices) => bar(), Ok(()) => baz(), } }) }); c.bench_function("jumps two Range", |b| { b.iter(|| { get_many_check_valid_jumps( &[black_box(1)..black_box(5), black_box(7)..black_box(8)], black_box(10), ) }) }); c.bench_function("jumps two RangeInclusive", |b| { b.iter(|| { get_many_check_valid_jumps( &[black_box(1)..=black_box(5), black_box(7)..=black_box(8)], black_box(10), ) }) }); c.bench_function("acc two usize", |b| { b.iter(|| get_many_check_valid_acc(&[black_box(1), black_box(5)], black_box(10))) }); c.bench_function("acc two usize unwrap", |b| { b.iter(|| get_many_check_valid_acc(&[black_box(1), black_box(5)], black_box(10)).unwrap()) }); c.bench_function("acc two usize ok", |b| { b.iter(|| get_many_check_valid_acc(&[black_box(1), black_box(5)], black_box(10)).ok()) }); c.bench_function("acc three usize", |b| { b.iter(|| { get_many_check_valid_acc(&[black_box(1), black_box(5), black_box(7)], black_box(10)) }) }); c.bench_function("acc three usize match", |b| { b.iter(|| { match get_many_check_valid_jumps( &[black_box(1), black_box(5), black_box(7)], black_box(10), ) { Err(GetManyMutError::IndexOutOfBounds) => foo(), Err(GetManyMutError::OverlappingIndices) => bar(), Ok(()) => baz(), } }) }); c.bench_function("acc two Range", |b| { b.iter(|| { get_many_check_valid_acc( &[black_box(1)..black_box(5), black_box(7)..black_box(8)], black_box(10), ) }) }); c.bench_function("acc two RangeInclusive", |b| { b.iter(|| { get_many_check_valid_acc( &[black_box(1)..=black_box(5), black_box(7)..=black_box(8)], black_box(10), ) }) }); } criterion_group!(benches, bench_method); criterion_main!(benches); ``` Benchmark results: ```none jumps two usize time: [586.44 ps 590.20 ps 594.50 ps] jumps two usize unwrap time: [390.44 ps 393.63 ps 397.44 ps] jumps two usize ok time: [585.52 ps 591.74 ps 599.38 ps] jumps three usize time: [976.51 ps 983.79 ps 991.51 ps] jumps three usize match time: [390.82 ps 393.80 ps 397.07 ps] jumps two Range time: [1.2583 ns 1.2640 ns 1.2695 ns] jumps two RangeInclusive time: [1.2673 ns 1.2770 ns 1.2877 ns] acc two usize time: [592.63 ps 596.44 ps 600.52 ps] acc two usize unwrap time: [582.65 ps 587.07 ps 591.90 ps] acc two usize ok time: [581.59 ps 587.82 ps 595.71 ps] acc three usize time: [894.69 ps 901.23 ps 908.24 ps] acc three usize match time: [392.68 ps 395.73 ps 399.17 ps] acc two Range time: [1.5531 ns 1.5617 ns 1.5711 ns] acc two RangeInclusive time: [1.5746 ns 1.5840 ns 1.5939 ns] ``` |
||
---|---|---|
.. | ||
benches | ||
src | ||
tests | ||
Cargo.toml |