bench1.rs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877
  1. use criterion::{black_box, criterion_group, criterion_main, Criterion};
  2. use itertools::Itertools;
  3. use itertools::free::cloned;
  4. use itertools::iproduct;
  5. use std::iter::repeat;
  6. use std::cmp;
  7. use std::ops::{Add, Range};
  8. mod extra;
  9. use crate::extra::ZipSlices;
  10. fn slice_iter(c: &mut Criterion) {
  11. let xs: Vec<_> = repeat(1i32).take(20).collect();
  12. c.bench_function("slice iter", move |b| {
  13. b.iter(|| for elt in xs.iter() {
  14. black_box(elt);
  15. })
  16. });
  17. }
  18. fn slice_iter_rev(c: &mut Criterion) {
  19. let xs: Vec<_> = repeat(1i32).take(20).collect();
  20. c.bench_function("slice iter rev", move |b| {
  21. b.iter(|| for elt in xs.iter().rev() {
  22. black_box(elt);
  23. })
  24. });
  25. }
  26. fn zip_default_zip(c: &mut Criterion) {
  27. let xs = vec![0; 1024];
  28. let ys = vec![0; 768];
  29. let xs = black_box(xs);
  30. let ys = black_box(ys);
  31. c.bench_function("zip default zip", move |b| {
  32. b.iter(|| {
  33. for (&x, &y) in xs.iter().zip(&ys) {
  34. black_box(x);
  35. black_box(y);
  36. }
  37. })
  38. });
  39. }
  40. fn zipdot_i32_default_zip(c: &mut Criterion) {
  41. let xs = vec![2; 1024];
  42. let ys = vec![2; 768];
  43. let xs = black_box(xs);
  44. let ys = black_box(ys);
  45. c.bench_function("zipdot i32 default zip", move |b| {
  46. b.iter(|| {
  47. let mut s = 0;
  48. for (&x, &y) in xs.iter().zip(&ys) {
  49. s += x * y;
  50. }
  51. s
  52. })
  53. });
  54. }
  55. fn zipdot_f32_default_zip(c: &mut Criterion) {
  56. let xs = vec![2f32; 1024];
  57. let ys = vec![2f32; 768];
  58. let xs = black_box(xs);
  59. let ys = black_box(ys);
  60. c.bench_function("zipdot f32 default zip", move |b| {
  61. b.iter(|| {
  62. let mut s = 0.;
  63. for (&x, &y) in xs.iter().zip(&ys) {
  64. s += x * y;
  65. }
  66. s
  67. })
  68. });
  69. }
  70. fn zip_default_zip3(c: &mut Criterion) {
  71. let xs = vec![0; 1024];
  72. let ys = vec![0; 768];
  73. let zs = vec![0; 766];
  74. let xs = black_box(xs);
  75. let ys = black_box(ys);
  76. let zs = black_box(zs);
  77. c.bench_function("zip default zip3", move |b| {
  78. b.iter(|| {
  79. for ((&x, &y), &z) in xs.iter().zip(&ys).zip(&zs) {
  80. black_box(x);
  81. black_box(y);
  82. black_box(z);
  83. }
  84. })
  85. });
  86. }
  87. fn zip_slices_ziptuple(c: &mut Criterion) {
  88. let xs = vec![0; 1024];
  89. let ys = vec![0; 768];
  90. c.bench_function("zip slices ziptuple", move |b| {
  91. b.iter(|| {
  92. let xs = black_box(&xs);
  93. let ys = black_box(&ys);
  94. for (&x, &y) in itertools::multizip((xs, ys)) {
  95. black_box(x);
  96. black_box(y);
  97. }
  98. })
  99. });
  100. }
  101. fn zipslices(c: &mut Criterion) {
  102. let xs = vec![0; 1024];
  103. let ys = vec![0; 768];
  104. let xs = black_box(xs);
  105. let ys = black_box(ys);
  106. c.bench_function("zipslices", move |b| {
  107. b.iter(|| {
  108. for (&x, &y) in ZipSlices::new(&xs, &ys) {
  109. black_box(x);
  110. black_box(y);
  111. }
  112. })
  113. });
  114. }
  115. fn zipslices_mut(c: &mut Criterion) {
  116. let xs = vec![0; 1024];
  117. let ys = vec![0; 768];
  118. let xs = black_box(xs);
  119. let mut ys = black_box(ys);
  120. c.bench_function("zipslices mut", move |b| {
  121. b.iter(|| {
  122. for (&x, &mut y) in ZipSlices::from_slices(&xs[..], &mut ys[..]) {
  123. black_box(x);
  124. black_box(y);
  125. }
  126. })
  127. });
  128. }
  129. fn zipdot_i32_zipslices(c: &mut Criterion) {
  130. let xs = vec![2; 1024];
  131. let ys = vec![2; 768];
  132. let xs = black_box(xs);
  133. let ys = black_box(ys);
  134. c.bench_function("zipdot i32 zipslices", move |b| {
  135. b.iter(|| {
  136. let mut s = 0i32;
  137. for (&x, &y) in ZipSlices::new(&xs, &ys) {
  138. s += x * y;
  139. }
  140. s
  141. })
  142. });
  143. }
  144. fn zipdot_f32_zipslices(c: &mut Criterion) {
  145. let xs = vec![2f32; 1024];
  146. let ys = vec![2f32; 768];
  147. let xs = black_box(xs);
  148. let ys = black_box(ys);
  149. c.bench_function("zipdot f32 zipslices", move |b| {
  150. b.iter(|| {
  151. let mut s = 0.;
  152. for (&x, &y) in ZipSlices::new(&xs, &ys) {
  153. s += x * y;
  154. }
  155. s
  156. })
  157. });
  158. }
  159. fn zip_checked_counted_loop(c: &mut Criterion) {
  160. let xs = vec![0; 1024];
  161. let ys = vec![0; 768];
  162. let xs = black_box(xs);
  163. let ys = black_box(ys);
  164. c.bench_function("zip checked counted loop", move |b| {
  165. b.iter(|| {
  166. // Must slice to equal lengths, and then bounds checks are eliminated!
  167. let len = cmp::min(xs.len(), ys.len());
  168. let xs = &xs[..len];
  169. let ys = &ys[..len];
  170. for i in 0..len {
  171. let x = xs[i];
  172. let y = ys[i];
  173. black_box(x);
  174. black_box(y);
  175. }
  176. })
  177. });
  178. }
  179. fn zipdot_i32_checked_counted_loop(c: &mut Criterion) {
  180. let xs = vec![2; 1024];
  181. let ys = vec![2; 768];
  182. let xs = black_box(xs);
  183. let ys = black_box(ys);
  184. c.bench_function("zipdot i32 checked counted loop", move |b| {
  185. b.iter(|| {
  186. // Must slice to equal lengths, and then bounds checks are eliminated!
  187. let len = cmp::min(xs.len(), ys.len());
  188. let xs = &xs[..len];
  189. let ys = &ys[..len];
  190. let mut s = 0i32;
  191. for i in 0..len {
  192. s += xs[i] * ys[i];
  193. }
  194. s
  195. })
  196. });
  197. }
  198. fn zipdot_f32_checked_counted_loop(c: &mut Criterion) {
  199. let xs = vec![2f32; 1024];
  200. let ys = vec![2f32; 768];
  201. let xs = black_box(xs);
  202. let ys = black_box(ys);
  203. c.bench_function("zipdot f32 checked counted loop", move |b| {
  204. b.iter(|| {
  205. // Must slice to equal lengths, and then bounds checks are eliminated!
  206. let len = cmp::min(xs.len(), ys.len());
  207. let xs = &xs[..len];
  208. let ys = &ys[..len];
  209. let mut s = 0.;
  210. for i in 0..len {
  211. s += xs[i] * ys[i];
  212. }
  213. s
  214. })
  215. });
  216. }
  217. fn zipdot_f32_checked_counted_unrolled_loop(c: &mut Criterion) {
  218. let xs = vec![2f32; 1024];
  219. let ys = vec![2f32; 768];
  220. let xs = black_box(xs);
  221. let ys = black_box(ys);
  222. c.bench_function("zipdot f32 checked counted unrolled loop", move |b| {
  223. b.iter(|| {
  224. // Must slice to equal lengths, and then bounds checks are eliminated!
  225. let len = cmp::min(xs.len(), ys.len());
  226. let mut xs = &xs[..len];
  227. let mut ys = &ys[..len];
  228. let mut s = 0.;
  229. let (mut p0, mut p1, mut p2, mut p3, mut p4, mut p5, mut p6, mut p7) =
  230. (0., 0., 0., 0., 0., 0., 0., 0.);
  231. // how to unroll and have bounds checks eliminated (by cristicbz)
  232. // split sum into eight parts to enable vectorization (by bluss)
  233. while xs.len() >= 8 {
  234. p0 += xs[0] * ys[0];
  235. p1 += xs[1] * ys[1];
  236. p2 += xs[2] * ys[2];
  237. p3 += xs[3] * ys[3];
  238. p4 += xs[4] * ys[4];
  239. p5 += xs[5] * ys[5];
  240. p6 += xs[6] * ys[6];
  241. p7 += xs[7] * ys[7];
  242. xs = &xs[8..];
  243. ys = &ys[8..];
  244. }
  245. s += p0 + p4;
  246. s += p1 + p5;
  247. s += p2 + p6;
  248. s += p3 + p7;
  249. for i in 0..xs.len() {
  250. s += xs[i] * ys[i];
  251. }
  252. s
  253. })
  254. });
  255. }
  256. fn zip_unchecked_counted_loop(c: &mut Criterion) {
  257. let xs = vec![0; 1024];
  258. let ys = vec![0; 768];
  259. let xs = black_box(xs);
  260. let ys = black_box(ys);
  261. c.bench_function("zip unchecked counted loop", move |b| {
  262. b.iter(|| {
  263. let len = cmp::min(xs.len(), ys.len());
  264. for i in 0..len {
  265. unsafe {
  266. let x = *xs.get_unchecked(i);
  267. let y = *ys.get_unchecked(i);
  268. black_box(x);
  269. black_box(y);
  270. }
  271. }
  272. })
  273. });
  274. }
  275. fn zipdot_i32_unchecked_counted_loop(c: &mut Criterion) {
  276. let xs = vec![2; 1024];
  277. let ys = vec![2; 768];
  278. let xs = black_box(xs);
  279. let ys = black_box(ys);
  280. c.bench_function("zipdot i32 unchecked counted loop", move |b| {
  281. b.iter(|| {
  282. let len = cmp::min(xs.len(), ys.len());
  283. let mut s = 0i32;
  284. for i in 0..len {
  285. unsafe {
  286. let x = *xs.get_unchecked(i);
  287. let y = *ys.get_unchecked(i);
  288. s += x * y;
  289. }
  290. }
  291. s
  292. })
  293. });
  294. }
  295. fn zipdot_f32_unchecked_counted_loop(c: &mut Criterion) {
  296. let xs = vec![2.; 1024];
  297. let ys = vec![2.; 768];
  298. let xs = black_box(xs);
  299. let ys = black_box(ys);
  300. c.bench_function("zipdot f32 unchecked counted loop", move |b| {
  301. b.iter(|| {
  302. let len = cmp::min(xs.len(), ys.len());
  303. let mut s = 0f32;
  304. for i in 0..len {
  305. unsafe {
  306. let x = *xs.get_unchecked(i);
  307. let y = *ys.get_unchecked(i);
  308. s += x * y;
  309. }
  310. }
  311. s
  312. })
  313. });
  314. }
  315. fn zip_unchecked_counted_loop3(c: &mut Criterion) {
  316. let xs = vec![0; 1024];
  317. let ys = vec![0; 768];
  318. let zs = vec![0; 766];
  319. let xs = black_box(xs);
  320. let ys = black_box(ys);
  321. let zs = black_box(zs);
  322. c.bench_function("zip unchecked counted loop3", move |b| {
  323. b.iter(|| {
  324. let len = cmp::min(xs.len(), cmp::min(ys.len(), zs.len()));
  325. for i in 0..len {
  326. unsafe {
  327. let x = *xs.get_unchecked(i);
  328. let y = *ys.get_unchecked(i);
  329. let z = *zs.get_unchecked(i);
  330. black_box(x);
  331. black_box(y);
  332. black_box(z);
  333. }
  334. }
  335. })
  336. });
  337. }
  338. fn group_by_lazy_1(c: &mut Criterion) {
  339. let mut data = vec![0; 1024];
  340. for (index, elt) in data.iter_mut().enumerate() {
  341. *elt = index / 10;
  342. }
  343. let data = black_box(data);
  344. c.bench_function("group by lazy 1", move |b| {
  345. b.iter(|| {
  346. for (_key, group) in &data.iter().group_by(|elt| **elt) {
  347. for elt in group {
  348. black_box(elt);
  349. }
  350. }
  351. })
  352. });
  353. }
  354. fn group_by_lazy_2(c: &mut Criterion) {
  355. let mut data = vec![0; 1024];
  356. for (index, elt) in data.iter_mut().enumerate() {
  357. *elt = index / 2;
  358. }
  359. let data = black_box(data);
  360. c.bench_function("group by lazy 2", move |b| {
  361. b.iter(|| {
  362. for (_key, group) in &data.iter().group_by(|elt| **elt) {
  363. for elt in group {
  364. black_box(elt);
  365. }
  366. }
  367. })
  368. });
  369. }
  370. fn slice_chunks(c: &mut Criterion) {
  371. let data = vec![0; 1024];
  372. let data = black_box(data);
  373. let sz = black_box(10);
  374. c.bench_function("slice chunks", move |b| {
  375. b.iter(|| {
  376. for group in data.chunks(sz) {
  377. for elt in group {
  378. black_box(elt);
  379. }
  380. }
  381. })
  382. });
  383. }
  384. fn chunks_lazy_1(c: &mut Criterion) {
  385. let data = vec![0; 1024];
  386. let data = black_box(data);
  387. let sz = black_box(10);
  388. c.bench_function("chunks lazy 1", move |b| {
  389. b.iter(|| {
  390. for group in &data.iter().chunks(sz) {
  391. for elt in group {
  392. black_box(elt);
  393. }
  394. }
  395. })
  396. });
  397. }
  398. fn equal(c: &mut Criterion) {
  399. let data = vec![7; 1024];
  400. let l = data.len();
  401. let alpha = black_box(&data[1..]);
  402. let beta = black_box(&data[..l - 1]);
  403. c.bench_function("equal", move |b| {
  404. b.iter(|| {
  405. itertools::equal(alpha, beta)
  406. })
  407. });
  408. }
  409. fn merge_default(c: &mut Criterion) {
  410. let mut data1 = vec![0; 1024];
  411. let mut data2 = vec![0; 800];
  412. let mut x = 0;
  413. for (_, elt) in data1.iter_mut().enumerate() {
  414. *elt = x;
  415. x += 1;
  416. }
  417. let mut y = 0;
  418. for (i, elt) in data2.iter_mut().enumerate() {
  419. *elt += y;
  420. if i % 3 == 0 {
  421. y += 3;
  422. } else {
  423. y += 0;
  424. }
  425. }
  426. let data1 = black_box(data1);
  427. let data2 = black_box(data2);
  428. c.bench_function("merge default", move |b| {
  429. b.iter(|| {
  430. data1.iter().merge(&data2).count()
  431. })
  432. });
  433. }
  434. fn merge_by_cmp(c: &mut Criterion) {
  435. let mut data1 = vec![0; 1024];
  436. let mut data2 = vec![0; 800];
  437. let mut x = 0;
  438. for (_, elt) in data1.iter_mut().enumerate() {
  439. *elt = x;
  440. x += 1;
  441. }
  442. let mut y = 0;
  443. for (i, elt) in data2.iter_mut().enumerate() {
  444. *elt += y;
  445. if i % 3 == 0 {
  446. y += 3;
  447. } else {
  448. y += 0;
  449. }
  450. }
  451. let data1 = black_box(data1);
  452. let data2 = black_box(data2);
  453. c.bench_function("merge by cmp", move |b| {
  454. b.iter(|| {
  455. data1.iter().merge_by(&data2, PartialOrd::le).count()
  456. })
  457. });
  458. }
  459. fn merge_by_lt(c: &mut Criterion) {
  460. let mut data1 = vec![0; 1024];
  461. let mut data2 = vec![0; 800];
  462. let mut x = 0;
  463. for (_, elt) in data1.iter_mut().enumerate() {
  464. *elt = x;
  465. x += 1;
  466. }
  467. let mut y = 0;
  468. for (i, elt) in data2.iter_mut().enumerate() {
  469. *elt += y;
  470. if i % 3 == 0 {
  471. y += 3;
  472. } else {
  473. y += 0;
  474. }
  475. }
  476. let data1 = black_box(data1);
  477. let data2 = black_box(data2);
  478. c.bench_function("merge by lt", move |b| {
  479. b.iter(|| {
  480. data1.iter().merge_by(&data2, |a, b| a <= b).count()
  481. })
  482. });
  483. }
  484. fn kmerge_default(c: &mut Criterion) {
  485. let mut data1 = vec![0; 1024];
  486. let mut data2 = vec![0; 800];
  487. let mut x = 0;
  488. for (_, elt) in data1.iter_mut().enumerate() {
  489. *elt = x;
  490. x += 1;
  491. }
  492. let mut y = 0;
  493. for (i, elt) in data2.iter_mut().enumerate() {
  494. *elt += y;
  495. if i % 3 == 0 {
  496. y += 3;
  497. } else {
  498. y += 0;
  499. }
  500. }
  501. let data1 = black_box(data1);
  502. let data2 = black_box(data2);
  503. let its = &[data1.iter(), data2.iter()];
  504. c.bench_function("kmerge default", move |b| {
  505. b.iter(|| {
  506. its.iter().cloned().kmerge().count()
  507. })
  508. });
  509. }
  510. fn kmerge_tenway(c: &mut Criterion) {
  511. let mut data = vec![0; 10240];
  512. let mut state = 1729u16;
  513. fn rng(state: &mut u16) -> u16 {
  514. let new = state.wrapping_mul(31421) + 6927;
  515. *state = new;
  516. new
  517. }
  518. for elt in &mut data {
  519. *elt = rng(&mut state);
  520. }
  521. let mut chunks = Vec::new();
  522. let mut rest = &mut data[..];
  523. while rest.len() > 0 {
  524. let chunk_len = 1 + rng(&mut state) % 512;
  525. let chunk_len = cmp::min(rest.len(), chunk_len as usize);
  526. let (fst, tail) = {rest}.split_at_mut(chunk_len);
  527. fst.sort();
  528. chunks.push(fst.iter().cloned());
  529. rest = tail;
  530. }
  531. // println!("Chunk lengths: {}", chunks.iter().format_with(", ", |elt, f| f(&elt.len())));
  532. c.bench_function("kmerge tenway", move |b| {
  533. b.iter(|| {
  534. chunks.iter().cloned().kmerge().count()
  535. })
  536. });
  537. }
  538. fn fast_integer_sum<I>(iter: I) -> I::Item
  539. where I: IntoIterator,
  540. I::Item: Default + Add<Output=I::Item>
  541. {
  542. iter.into_iter().fold(<_>::default(), |x, y| x + y)
  543. }
  544. fn step_vec_2(c: &mut Criterion) {
  545. let v = vec![0; 1024];
  546. c.bench_function("step vec 2", move |b| {
  547. b.iter(|| {
  548. fast_integer_sum(cloned(v.iter().step_by(2)))
  549. })
  550. });
  551. }
  552. fn step_vec_10(c: &mut Criterion) {
  553. let v = vec![0; 1024];
  554. c.bench_function("step vec 10", move |b| {
  555. b.iter(|| {
  556. fast_integer_sum(cloned(v.iter().step_by(10)))
  557. })
  558. });
  559. }
  560. fn step_range_2(c: &mut Criterion) {
  561. let v = black_box(0..1024);
  562. c.bench_function("step range 2", move |b| {
  563. b.iter(|| {
  564. fast_integer_sum(v.clone().step_by(2))
  565. })
  566. });
  567. }
  568. fn step_range_10(c: &mut Criterion) {
  569. let v = black_box(0..1024);
  570. c.bench_function("step range 10", move |b| {
  571. b.iter(|| {
  572. fast_integer_sum(v.clone().step_by(10))
  573. })
  574. });
  575. }
  576. fn cartesian_product_iterator(c: &mut Criterion) {
  577. let xs = vec![0; 16];
  578. c.bench_function("cartesian product iterator", move |b| {
  579. b.iter(|| {
  580. let mut sum = 0;
  581. for (&x, &y, &z) in iproduct!(&xs, &xs, &xs) {
  582. sum += x;
  583. sum += y;
  584. sum += z;
  585. }
  586. sum
  587. })
  588. });
  589. }
  590. fn cartesian_product_fold(c: &mut Criterion) {
  591. let xs = vec![0; 16];
  592. c.bench_function("cartesian product fold", move |b| {
  593. b.iter(|| {
  594. let mut sum = 0;
  595. iproduct!(&xs, &xs, &xs).fold((), |(), (&x, &y, &z)| {
  596. sum += x;
  597. sum += y;
  598. sum += z;
  599. });
  600. sum
  601. })
  602. });
  603. }
  604. fn multi_cartesian_product_iterator(c: &mut Criterion) {
  605. let xs = [vec![0; 16], vec![0; 16], vec![0; 16]];
  606. c.bench_function("multi cartesian product iterator", move |b| {
  607. b.iter(|| {
  608. let mut sum = 0;
  609. for x in xs.iter().multi_cartesian_product() {
  610. sum += x[0];
  611. sum += x[1];
  612. sum += x[2];
  613. }
  614. sum
  615. })
  616. });
  617. }
  618. fn multi_cartesian_product_fold(c: &mut Criterion) {
  619. let xs = [vec![0; 16], vec![0; 16], vec![0; 16]];
  620. c.bench_function("multi cartesian product fold", move |b| {
  621. b.iter(|| {
  622. let mut sum = 0;
  623. xs.iter().multi_cartesian_product().fold((), |(), x| {
  624. sum += x[0];
  625. sum += x[1];
  626. sum += x[2];
  627. });
  628. sum
  629. })
  630. });
  631. }
  632. fn cartesian_product_nested_for(c: &mut Criterion) {
  633. let xs = vec![0; 16];
  634. c.bench_function("cartesian product nested for", move |b| {
  635. b.iter(|| {
  636. let mut sum = 0;
  637. for &x in &xs {
  638. for &y in &xs {
  639. for &z in &xs {
  640. sum += x;
  641. sum += y;
  642. sum += z;
  643. }
  644. }
  645. }
  646. sum
  647. })
  648. });
  649. }
  650. fn all_equal(c: &mut Criterion) {
  651. let mut xs = vec![0; 5_000_000];
  652. xs.extend(vec![1; 5_000_000]);
  653. c.bench_function("all equal", move |b| {
  654. b.iter(|| xs.iter().all_equal())
  655. });
  656. }
  657. fn all_equal_for(c: &mut Criterion) {
  658. let mut xs = vec![0; 5_000_000];
  659. xs.extend(vec![1; 5_000_000]);
  660. c.bench_function("all equal for", move |b| {
  661. b.iter(|| {
  662. for &x in &xs {
  663. if x != xs[0] {
  664. return false;
  665. }
  666. }
  667. true
  668. })
  669. });
  670. }
  671. fn all_equal_default(c: &mut Criterion) {
  672. let mut xs = vec![0; 5_000_000];
  673. xs.extend(vec![1; 5_000_000]);
  674. c.bench_function("all equal default", move |b| {
  675. b.iter(|| xs.iter().dedup().nth(1).is_none())
  676. });
  677. }
  678. const PERM_COUNT: usize = 6;
  679. fn permutations_iter(c: &mut Criterion) {
  680. struct NewIterator(Range<usize>);
  681. impl Iterator for NewIterator {
  682. type Item = usize;
  683. fn next(&mut self) -> Option<Self::Item> {
  684. self.0.next()
  685. }
  686. }
  687. c.bench_function("permutations iter", move |b| {
  688. b.iter(|| {
  689. for _ in NewIterator(0..PERM_COUNT).permutations(PERM_COUNT) {
  690. }
  691. })
  692. });
  693. }
  694. fn permutations_range(c: &mut Criterion) {
  695. c.bench_function("permutations range", move |b| {
  696. b.iter(|| {
  697. for _ in (0..PERM_COUNT).permutations(PERM_COUNT) {
  698. }
  699. })
  700. });
  701. }
  702. fn permutations_slice(c: &mut Criterion) {
  703. let v = (0..PERM_COUNT).collect_vec();
  704. c.bench_function("permutations slice", move |b| {
  705. b.iter(|| {
  706. for _ in v.as_slice().iter().permutations(PERM_COUNT) {
  707. }
  708. })
  709. });
  710. }
  711. criterion_group!(
  712. benches,
  713. slice_iter,
  714. slice_iter_rev,
  715. zip_default_zip,
  716. zipdot_i32_default_zip,
  717. zipdot_f32_default_zip,
  718. zip_default_zip3,
  719. zip_slices_ziptuple,
  720. zipslices,
  721. zipslices_mut,
  722. zipdot_i32_zipslices,
  723. zipdot_f32_zipslices,
  724. zip_checked_counted_loop,
  725. zipdot_i32_checked_counted_loop,
  726. zipdot_f32_checked_counted_loop,
  727. zipdot_f32_checked_counted_unrolled_loop,
  728. zip_unchecked_counted_loop,
  729. zipdot_i32_unchecked_counted_loop,
  730. zipdot_f32_unchecked_counted_loop,
  731. zip_unchecked_counted_loop3,
  732. group_by_lazy_1,
  733. group_by_lazy_2,
  734. slice_chunks,
  735. chunks_lazy_1,
  736. equal,
  737. merge_default,
  738. merge_by_cmp,
  739. merge_by_lt,
  740. kmerge_default,
  741. kmerge_tenway,
  742. step_vec_2,
  743. step_vec_10,
  744. step_range_2,
  745. step_range_10,
  746. cartesian_product_iterator,
  747. cartesian_product_fold,
  748. multi_cartesian_product_iterator,
  749. multi_cartesian_product_fold,
  750. cartesian_product_nested_for,
  751. all_equal,
  752. all_equal_for,
  753. all_equal_default,
  754. permutations_iter,
  755. permutations_range,
  756. permutations_slice,
  757. );
  758. criterion_main!(benches);