Hello,
I recently working on a pretty small, no-std, zero-dependency crate called first-err
(primarily for fun), and I'm so exciting to share it with everyone.
This crate is specifically designed to replace the following pattern without allocation:
fn fallible_sum<'a>(values: &'a [&str]) -> Result<u32, &'a str> {
let sum = values
.iter() // start an iteration.
.map(|s| s.parse::<u32>().map_err(|_| *s))
.collect::<Result<Vec<u32>, &str>>()? // find first err (and alloc a vec in here)
.into_iter() // and then continue iterating
.sum::<u32>();
Ok(sum)
}
fn main() {
let values = &["1", "2", "three", "4", "5"];
assert_eq!(fallible_sum(values), Err("three"));
}
The above code use first-err
would be:
use first_err::FirstErr;
fn fallible_sum<'a>(values: &'a [&str]) -> Result<u32, &'a str> {
values
.iter()
.map(|s| s.parse::<u32>().map_err(|_| *s)) // Iterator<Item = Result<u32, &str>>
.first_err_or_else(|iter1| { // iter1: impl Iterator<Item = u32>
iter1.sum::<u32>()
})
}
fn main() {
let values = &["1", "2", "three", "4", "5"];
assert_eq!(fallible_sum(values), Err("three"));
}
Note: This crate also support the same logic in Iterator<Item = Option<T>>
scenarios.
I guess the APIs are pretty clear and intuition, and hard to using wrong. If you found any problems with it, just let me know, thanks. I may tweak it and (hopefully not) introduce breaking change if something really important.
Performance
This crate should be roughly on par with hand-written loops in performance aspect, and I already write some benchmark code to verify it. You can check the results as follows, or just run yourself.
Benchmark Results
Environment
- cpu: AMD Ryzen 5 3600 6-Core Processor
- os: Debian GNU/Linux 12 (bookworm)
- kernel: Linux 6.1.0-10-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.38-1 (2023-07-14)
- rustc: 1.72.0 (5680fa18f 2023-08-23)
- cargo: 1.72.0 (103a7ff2e 2023-08-15)
- first-err: v0.2.0
- date: 2023-10-28
Results
test l1res::err_at_0______/__collect ... bench: 11 ns/iter (+/- 0)
test l1res::err_at_0______/_____loop ... bench: 1 ns/iter (+/- 0)
test l1res::err_at_0______/first_err ... bench: 2 ns/iter (+/- 0)
test l1res::err_at_10_____/__collect ... bench: 103 ns/iter (+/- 1)
test l1res::err_at_10_____/_____loop ... bench: 10 ns/iter (+/- 0)
test l1res::err_at_10_____/first_err ... bench: 11 ns/iter (+/- 6)
test l1res::err_at_100____/__collect ... bench: 314 ns/iter (+/- 3)
test l1res::err_at_100____/_____loop ... bench: 89 ns/iter (+/- 38)
test l1res::err_at_100____/first_err ... bench: 89 ns/iter (+/- 3)
test l1res::err_at_1000___/__collect ... bench: 1542 ns/iter (+/- 531)
test l1res::err_at_1000___/_____loop ... bench: 879 ns/iter (+/- 714)
test l1res::err_at_1000___/first_err ... bench: 900 ns/iter (+/- 785)
test l1res::err_at_10000__/__collect ... bench: 24843 ns/iter (+/- 6165)
test l1res::err_at_10000__/_____loop ... bench: 24066 ns/iter (+/- 8005)
test l1res::err_at_10000__/first_err ... bench: 10712 ns/iter (+/- 7917)
test l1res::err_at_99999__/__collect ... bench: 246043 ns/iter (+/- 10544)
test l1res::err_at_99999__/_____loop ... bench: 86958 ns/iter (+/- 77491)
test l1res::err_at_99999__/first_err ... bench: 87586 ns/iter (+/- 81596)
test l1res::err_not_exists/__collect ... bench: 256112 ns/iter (+/- 6170)
test l1res::err_not_exists/_____loop ... bench: 86596 ns/iter (+/- 60184)
test l1res::err_not_exists/first_err ... bench: 86703 ns/iter (+/- 71470)
test l2res::l1_err_at_0_______l2_err_at_1000___/__collect ... bench: 18 ns/iter (+/- 0)
test l2res::l1_err_at_0_______l2_err_at_1000___/_____loop ... bench: 11 ns/iter (+/- 0)
test l2res::l1_err_at_0_______l2_err_at_1000___/first_err ... bench: 10 ns/iter (+/- 0)
test l2res::l1_err_at_10______l2_err_at_1000___/__collect ... bench: 107 ns/iter (+/- 4)
test l2res::l1_err_at_10______l2_err_at_1000___/_____loop ... bench: 21 ns/iter (+/- 0)
test l2res::l1_err_at_10______l2_err_at_1000___/first_err ... bench: 20 ns/iter (+/- 0)
test l2res::l1_err_at_100_____l2_err_at_1000___/__collect ... bench: 379 ns/iter (+/- 8)
test l2res::l1_err_at_100_____l2_err_at_1000___/_____loop ... bench: 163 ns/iter (+/- 5)
test l2res::l1_err_at_100_____l2_err_at_1000___/first_err ... bench: 156 ns/iter (+/- 3)
test l2res::l1_err_at_1000____l2_err_at_1000___/__collect ... bench: 1924 ns/iter (+/- 7)
test l2res::l1_err_at_1000____l2_err_at_1000___/_____loop ... bench: 1446 ns/iter (+/- 12)
test l2res::l1_err_at_1000____l2_err_at_1000___/first_err ... bench: 1453 ns/iter (+/- 29)
test l2res::l1_err_at_10000___l2_err_at_1000___/__collect ... bench: 16222 ns/iter (+/- 555)
test l2res::l1_err_at_10000___l2_err_at_1000___/_____loop ... bench: 14432 ns/iter (+/- 5748)
test l2res::l1_err_at_10000___l2_err_at_1000___/first_err ... bench: 14363 ns/iter (+/- 5538)
test l2res::l1_err_at_99999___l2_err_at_1000___/__collect ... bench: 183241 ns/iter (+/- 2231)
test l2res::l1_err_at_99999___l2_err_at_1000___/_____loop ... bench: 143188 ns/iter (+/- 48487)
test l2res::l1_err_at_99999___l2_err_at_1000___/first_err ... bench: 139212 ns/iter (+/- 26714)
test l2res::l1_err_not_exists_l2_err_at_1000___/__collect ... bench: 180766 ns/iter (+/- 2712)
test l2res::l1_err_not_exists_l2_err_at_1000___/_____loop ... bench: 143152 ns/iter (+/- 680)
test l2res::l1_err_not_exists_l2_err_at_1000___/first_err ... bench: 140688 ns/iter (+/- 75539)
test l2res::l1_err_at_1000____l2_err_at_0______/__collect ... bench: 1921 ns/iter (+/- 22)
test l2res::l1_err_at_1000____l2_err_at_0______/_____loop ... bench: 1354 ns/iter (+/- 595)
test l2res::l1_err_at_1000____l2_err_at_0______/first_err ... bench: 1446 ns/iter (+/- 639)
test l2res::l1_err_at_1000____l2_err_at_10_____/__collect ... bench: 1892 ns/iter (+/- 29)
test l2res::l1_err_at_1000____l2_err_at_10_____/_____loop ... bench: 1668 ns/iter (+/- 762)
test l2res::l1_err_at_1000____l2_err_at_10_____/first_err ... bench: 1458 ns/iter (+/- 354)
test l2res::l1_err_at_1000____l2_err_at_100____/__collect ... bench: 1878 ns/iter (+/- 53)
test l2res::l1_err_at_1000____l2_err_at_100____/_____loop ... bench: 2784 ns/iter (+/- 537)
test l2res::l1_err_at_1000____l2_err_at_100____/first_err ... bench: 2948 ns/iter (+/- 715)
test l2res::l1_err_at_1000____l2_err_at_1000___/__collect #2 ... bench: 1884 ns/iter (+/- 68)
test l2res::l1_err_at_1000____l2_err_at_1000___/_____loop #2 ... bench: 1516 ns/iter (+/- 59)
test l2res::l1_err_at_1000____l2_err_at_1000___/first_err #2 ... bench: 1472 ns/iter (+/- 71)
test l2res::l1_err_at_1000____l2_err_at_10000__/__collect ... bench: 1937 ns/iter (+/- 22)
test l2res::l1_err_at_1000____l2_err_at_10000__/_____loop ... bench: 1514 ns/iter (+/- 43)
test l2res::l1_err_at_1000____l2_err_at_10000__/first_err ... bench: 1486 ns/iter (+/- 33)
test l2res::l1_err_at_1000____l2_err_at_99999__/__collect ... bench: 1912 ns/iter (+/- 36)
test l2res::l1_err_at_1000____l2_err_at_99999__/_____loop ... bench: 1446 ns/iter (+/- 9)
test l2res::l1_err_at_1000____l2_err_at_99999__/first_err ... bench: 1454 ns/iter (+/- 45)
test l2res::l1_err_at_1000____l2_err_not_exists/__collect ... bench: 1936 ns/iter (+/- 52)
test l2res::l1_err_at_1000____l2_err_not_exists/_____loop ... bench: 1512 ns/iter (+/- 83)
test l2res::l1_err_at_1000____l2_err_not_exists/first_err ... bench: 1450 ns/iter (+/- 8)
test l2res::l1_err_not_exists_l2_err_at_0______/__collect ... bench: 181537 ns/iter (+/- 3474)
test l2res::l1_err_not_exists_l2_err_at_0______/_____loop ... bench: 134772 ns/iter (+/- 39332)
test l2res::l1_err_not_exists_l2_err_at_0______/first_err ... bench: 142383 ns/iter (+/- 58778)
test l2res::l1_err_not_exists_l2_err_at_10_____/__collect ... bench: 185324 ns/iter (+/- 14065)
test l2res::l1_err_not_exists_l2_err_at_10_____/_____loop ... bench: 134675 ns/iter (+/- 39927)
test l2res::l1_err_not_exists_l2_err_at_10_____/first_err ... bench: 142835 ns/iter (+/- 58236)
test l2res::l1_err_not_exists_l2_err_at_100____/__collect ... bench: 179775 ns/iter (+/- 3277)
test l2res::l1_err_not_exists_l2_err_at_100____/_____loop ... bench: 143182 ns/iter (+/- 37429)
test l2res::l1_err_not_exists_l2_err_at_100____/first_err ... bench: 140019 ns/iter (+/- 1241)
test l2res::l1_err_not_exists_l2_err_at_1000___/__collect #2 ... bench: 180570 ns/iter (+/- 680)
test l2res::l1_err_not_exists_l2_err_at_1000___/_____loop #2 ... bench: 143217 ns/iter (+/- 2567)
test l2res::l1_err_not_exists_l2_err_at_1000___/first_err #2 ... bench: 140436 ns/iter (+/- 63962)
test l2res::l1_err_not_exists_l2_err_at_10000__/__collect ... bench: 184348 ns/iter (+/- 4317)
test l2res::l1_err_not_exists_l2_err_at_10000__/_____loop ... bench: 143244 ns/iter (+/- 241)
test l2res::l1_err_not_exists_l2_err_at_10000__/first_err ... bench: 141813 ns/iter (+/- 15499)
test l2res::l1_err_not_exists_l2_err_at_99999__/__collect ... bench: 260050 ns/iter (+/- 3608)
test l2res::l1_err_not_exists_l2_err_at_99999__/_____loop ... bench: 143346 ns/iter (+/- 4882)
test l2res::l1_err_not_exists_l2_err_at_99999__/first_err ... bench: 143413 ns/iter (+/- 3107)
test l2res::l1_err_at_0_______l2_err_not_exists/__collect ... bench: 18 ns/iter (+/- 0)
test l2res::l1_err_at_0_______l2_err_not_exists/_____loop ... bench: 11 ns/iter (+/- 0)
test l2res::l1_err_at_0_______l2_err_not_exists/first_err ... bench: 10 ns/iter (+/- 0)
test l2res::l1_err_at_10______l2_err_not_exists/__collect ... bench: 129 ns/iter (+/- 2)
test l2res::l1_err_at_10______l2_err_not_exists/_____loop ... bench: 20 ns/iter (+/- 0)
test l2res::l1_err_at_10______l2_err_not_exists/first_err ... bench: 20 ns/iter (+/- 0)
test l2res::l1_err_at_100_____l2_err_not_exists/__collect ... bench: 413 ns/iter (+/- 2)
test l2res::l1_err_at_100_____l2_err_not_exists/_____loop ... bench: 163 ns/iter (+/- 3)
test l2res::l1_err_at_100_____l2_err_not_exists/first_err ... bench: 154 ns/iter (+/- 1)
test l2res::l1_err_at_1000____l2_err_not_exists/__collect #2 ... bench: 1914 ns/iter (+/- 18)
test l2res::l1_err_at_1000____l2_err_not_exists/_____loop #2 ... bench: 1444 ns/iter (+/- 71)
test l2res::l1_err_at_1000____l2_err_not_exists/first_err #2 ... bench: 1484 ns/iter (+/- 20)
test l2res::l1_err_at_10000___l2_err_not_exists/__collect ... bench: 16071 ns/iter (+/- 188)
test l2res::l1_err_at_10000___l2_err_not_exists/_____loop ... bench: 14350 ns/iter (+/- 389)
test l2res::l1_err_at_10000___l2_err_not_exists/first_err ... bench: 14355 ns/iter (+/- 24)
test l2res::l1_err_at_99999___l2_err_not_exists/__collect ... bench: 179823 ns/iter (+/- 530)
test l2res::l1_err_at_99999___l2_err_not_exists/_____loop ... bench: 143386 ns/iter (+/- 2464)
test l2res::l1_err_at_99999___l2_err_not_exists/first_err ... bench: 143362 ns/iter (+/- 117)
test l2res::l1_err_not_exists_l2_err_not_exists/__collect ... bench: 269990 ns/iter (+/- 5142)
test l2res::l1_err_not_exists_l2_err_not_exists/_____loop ... bench: 143353 ns/iter (+/- 12659)
test l2res::l1_err_not_exists_l2_err_not_exists/first_err ... bench: 143382 ns/iter (+/- 150)
test l1opt::none_at_0______/__collect ... bench: 11 ns/iter (+/- 0)
test l1opt::none_at_0______/_____loop ... bench: 1 ns/iter (+/- 0)
test l1opt::none_at_0______/first_err ... bench: 2 ns/iter (+/- 0)
test l1opt::none_at_10_____/__collect ... bench: 112 ns/iter (+/- 1)
test l1opt::none_at_10_____/_____loop ... bench: 10 ns/iter (+/- 3)
test l1opt::none_at_10_____/first_err ... bench: 25 ns/iter (+/- 6)
test l1opt::none_at_100____/__collect ... bench: 364 ns/iter (+/- 3)
test l1opt::none_at_100____/_____loop ... bench: 263 ns/iter (+/- 70)
test l1opt::none_at_100____/first_err ... bench: 93 ns/iter (+/- 39)
test l1opt::none_at_1000___/__collect ... bench: 1566 ns/iter (+/- 216)
test l1opt::none_at_1000___/_____loop ... bench: 1927 ns/iter (+/- 772)
test l1opt::none_at_1000___/first_err ... bench: 1280 ns/iter (+/- 791)
test l1opt::none_at_10000__/__collect ... bench: 11772 ns/iter (+/- 5020)
test l1opt::none_at_10000__/_____loop ... bench: 8357 ns/iter (+/- 3201)
test l1opt::none_at_10000__/first_err ... bench: 7937 ns/iter (+/- 3679)
test l1opt::none_at_99999__/__collect ... bench: 263004 ns/iter (+/- 15409)
test l1opt::none_at_99999__/_____loop ... bench: 239036 ns/iter (+/- 78042)
test l1opt::none_at_99999__/first_err ... bench: 242659 ns/iter (+/- 132)
test l1opt::none_not_exists/__collect ... bench: 273014 ns/iter (+/- 28528)
test l1opt::none_not_exists/_____loop ... bench: 83924 ns/iter (+/- 32051)
test l1opt::none_not_exists/first_err ... bench: 79956 ns/iter (+/- 75761)
test l2opt::l1_none_at_0_______l2_none_at_1000___/__collect ... bench: 18 ns/iter (+/- 0)
test l2opt::l1_none_at_0_______l2_none_at_1000___/_____loop ... bench: 11 ns/iter (+/- 0)
test l2opt::l1_none_at_0_______l2_none_at_1000___/first_err ... bench: 10 ns/iter (+/- 0)
test l2opt::l1_none_at_10______l2_none_at_1000___/__collect ... bench: 120 ns/iter (+/- 1)
test l2opt::l1_none_at_10______l2_none_at_1000___/_____loop ... bench: 20 ns/iter (+/- 0)
test l2opt::l1_none_at_10______l2_none_at_1000___/first_err ... bench: 20 ns/iter (+/- 0)
test l2opt::l1_none_at_100_____l2_none_at_1000___/__collect ... bench: 359 ns/iter (+/- 18)
test l2opt::l1_none_at_100_____l2_none_at_1000___/_____loop ... bench: 154 ns/iter (+/- 0)
test l2opt::l1_none_at_100_____l2_none_at_1000___/first_err ... bench: 154 ns/iter (+/- 1)
test l2opt::l1_none_at_1000____l2_none_at_1000___/__collect ... bench: 1858 ns/iter (+/- 19)
test l2opt::l1_none_at_1000____l2_none_at_1000___/_____loop ... bench: 1444 ns/iter (+/- 2)
test l2opt::l1_none_at_1000____l2_none_at_1000___/first_err ... bench: 1460 ns/iter (+/- 87)
test l2opt::l1_none_at_10000___l2_none_at_1000___/__collect ... bench: 16062 ns/iter (+/- 256)
test l2opt::l1_none_at_10000___l2_none_at_1000___/_____loop ... bench: 14367 ns/iter (+/- 108)
test l2opt::l1_none_at_10000___l2_none_at_1000___/first_err ... bench: 14340 ns/iter (+/- 155)
test l2opt::l1_none_at_99999___l2_none_at_1000___/__collect ... bench: 180597 ns/iter (+/- 8952)
test l2opt::l1_none_at_99999___l2_none_at_1000___/_____loop ... bench: 143304 ns/iter (+/- 58020)
test l2opt::l1_none_at_99999___l2_none_at_1000___/first_err ... bench: 293926 ns/iter (+/- 82793)
test l2opt::l1_none_not_exists_l2_none_at_1000___/__collect ... bench: 182543 ns/iter (+/- 4375)
test l2opt::l1_none_not_exists_l2_none_at_1000___/_____loop ... bench: 143175 ns/iter (+/- 46427)
test l2opt::l1_none_not_exists_l2_none_at_1000___/first_err ... bench: 140369 ns/iter (+/- 1080)
test l2opt::l1_none_at_1000____l2_none_at_0______/__collect ... bench: 1940 ns/iter (+/- 53)
test l2opt::l1_none_at_1000____l2_none_at_0______/_____loop ... bench: 1357 ns/iter (+/- 14)
test l2opt::l1_none_at_1000____l2_none_at_0______/first_err ... bench: 1452 ns/iter (+/- 707)
test l2opt::l1_none_at_1000____l2_none_at_10_____/__collect ... bench: 1920 ns/iter (+/- 90)
test l2opt::l1_none_at_1000____l2_none_at_10_____/_____loop ... bench: 1358 ns/iter (+/- 675)
test l2opt::l1_none_at_1000____l2_none_at_10_____/first_err ... bench: 1453 ns/iter (+/- 50)
test l2opt::l1_none_at_1000____l2_none_at_100____/__collect ... bench: 1942 ns/iter (+/- 34)
test l2opt::l1_none_at_1000____l2_none_at_100____/_____loop ... bench: 1468 ns/iter (+/- 408)
test l2opt::l1_none_at_1000____l2_none_at_100____/first_err ... bench: 2951 ns/iter (+/- 663)
test l2opt::l1_none_at_1000____l2_none_at_1000___/__collect #2 ... bench: 1949 ns/iter (+/- 57)
test l2opt::l1_none_at_1000____l2_none_at_1000___/_____loop #2 ... bench: 1462 ns/iter (+/- 39)
test l2opt::l1_none_at_1000____l2_none_at_1000___/first_err #2 ... bench: 1451 ns/iter (+/- 14)
test l2opt::l1_none_at_1000____l2_none_at_10000__/__collect ... bench: 1954 ns/iter (+/- 34)
test l2opt::l1_none_at_1000____l2_none_at_10000__/_____loop ... bench: 1449 ns/iter (+/- 33)
test l2opt::l1_none_at_1000____l2_none_at_10000__/first_err ... bench: 1454 ns/iter (+/- 114)
test l2opt::l1_none_at_1000____l2_none_at_99999__/__collect ... bench: 1947 ns/iter (+/- 17)
test l2opt::l1_none_at_1000____l2_none_at_99999__/_____loop ... bench: 1510 ns/iter (+/- 57)
test l2opt::l1_none_at_1000____l2_none_at_99999__/first_err ... bench: 1454 ns/iter (+/- 51)
test l2opt::l1_none_at_1000____l2_none_not_exists/__collect ... bench: 1915 ns/iter (+/- 53)
test l2opt::l1_none_at_1000____l2_none_not_exists/_____loop ... bench: 1451 ns/iter (+/- 49)
test l2opt::l1_none_at_1000____l2_none_not_exists/first_err ... bench: 1460 ns/iter (+/- 99)
test l2opt::l1_none_not_exists_l2_none_at_0______/__collect ... bench: 180624 ns/iter (+/- 1317)
test l2opt::l1_none_not_exists_l2_none_at_0______/_____loop ... bench: 135205 ns/iter (+/- 53407)
test l2opt::l1_none_not_exists_l2_none_at_0______/first_err ... bench: 142770 ns/iter (+/- 77869)
test l2opt::l1_none_not_exists_l2_none_at_10_____/__collect ... bench: 178635 ns/iter (+/- 2068)
test l2opt::l1_none_not_exists_l2_none_at_10_____/_____loop ... bench: 134618 ns/iter (+/- 326)
test l2opt::l1_none_not_exists_l2_none_at_10_____/first_err ... bench: 142680 ns/iter (+/- 1325)
test l2opt::l1_none_not_exists_l2_none_at_100____/__collect ... bench: 180881 ns/iter (+/- 4920)
test l2opt::l1_none_not_exists_l2_none_at_100____/_____loop ... bench: 144097 ns/iter (+/- 66716)
test l2opt::l1_none_not_exists_l2_none_at_100____/first_err ... bench: 139882 ns/iter (+/- 47413)
test l2opt::l1_none_not_exists_l2_none_at_1000___/__collect #2 ... bench: 182234 ns/iter (+/- 1207)
test l2opt::l1_none_not_exists_l2_none_at_1000___/_____loop #2 ... bench: 143290 ns/iter (+/- 277)
test l2opt::l1_none_not_exists_l2_none_at_1000___/first_err #2 ... bench: 140271 ns/iter (+/- 2245)
test l2opt::l1_none_not_exists_l2_none_at_10000__/__collect ... bench: 183328 ns/iter (+/- 2854)
test l2opt::l1_none_not_exists_l2_none_at_10000__/_____loop ... bench: 143274 ns/iter (+/- 122)
test l2opt::l1_none_not_exists_l2_none_at_10000__/first_err ... bench: 141344 ns/iter (+/- 1163)
test l2opt::l1_none_not_exists_l2_none_at_99999__/__collect ... bench: 255029 ns/iter (+/- 4666)
test l2opt::l1_none_not_exists_l2_none_at_99999__/_____loop ... bench: 143897 ns/iter (+/- 642)
test l2opt::l1_none_not_exists_l2_none_at_99999__/first_err ... bench: 143559 ns/iter (+/- 1435)
test l2opt::l1_none_at_0_______l2_none_not_exists/__collect ... bench: 18 ns/iter (+/- 0)
test l2opt::l1_none_at_0_______l2_none_not_exists/_____loop ... bench: 11 ns/iter (+/- 0)
test l2opt::l1_none_at_0_______l2_none_not_exists/first_err ... bench: 10 ns/iter (+/- 0)
test l2opt::l1_none_at_10______l2_none_not_exists/__collect ... bench: 123 ns/iter (+/- 2)
test l2opt::l1_none_at_10______l2_none_not_exists/_____loop ... bench: 20 ns/iter (+/- 0)
test l2opt::l1_none_at_10______l2_none_not_exists/first_err ... bench: 21 ns/iter (+/- 0)
test l2opt::l1_none_at_100_____l2_none_not_exists/__collect ... bench: 383 ns/iter (+/- 22)
test l2opt::l1_none_at_100_____l2_none_not_exists/_____loop ... bench: 155 ns/iter (+/- 2)
test l2opt::l1_none_at_100_____l2_none_not_exists/first_err ... bench: 154 ns/iter (+/- 4)
test l2opt::l1_none_at_1000____l2_none_not_exists/__collect #2 ... bench: 1926 ns/iter (+/- 59)
test l2opt::l1_none_at_1000____l2_none_not_exists/_____loop #2 ... bench: 1445 ns/iter (+/- 50)
test l2opt::l1_none_at_1000____l2_none_not_exists/first_err #2 ... bench: 1450 ns/iter (+/- 12)
test l2opt::l1_none_at_10000___l2_none_not_exists/__collect ... bench: 16122 ns/iter (+/- 144)
test l2opt::l1_none_at_10000___l2_none_not_exists/_____loop ... bench: 14369 ns/iter (+/- 185)
test l2opt::l1_none_at_10000___l2_none_not_exists/first_err ... bench: 14423 ns/iter (+/- 272)
test l2opt::l1_none_at_99999___l2_none_not_exists/__collect ... bench: 179766 ns/iter (+/- 1038)
test l2opt::l1_none_at_99999___l2_none_not_exists/_____loop ... bench: 143399 ns/iter (+/- 762)
test l2opt::l1_none_at_99999___l2_none_not_exists/first_err ... bench: 143623 ns/iter (+/- 4965)
test l2opt::l1_none_not_exists_l2_none_not_exists/__collect ... bench: 274073 ns/iter (+/- 4701)
test l2opt::l1_none_not_exists_l2_none_not_exists/_____loop ... bench: 143589 ns/iter (+/- 3224)
test l2opt::l1_none_not_exists_l2_none_not_exists/first_err ... bench: 143612 ns/iter (+/- 302)