From 070c83d5a96d26240824abdb3c38ecdb860710f5 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Mon, 5 Aug 2019 11:32:27 +0200 Subject: [PATCH 1/2] add contains benchmarks --- .../tiny_list/tests.rs | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/librustc_data_structures/tiny_list/tests.rs b/src/librustc_data_structures/tiny_list/tests.rs index 8374659e1e6..0142631590c 100644 --- a/src/librustc_data_structures/tiny_list/tests.rs +++ b/src/librustc_data_structures/tiny_list/tests.rs @@ -1,7 +1,7 @@ use super::*; extern crate test; -use test::Bencher; +use test::{Bencher, black_box}; #[test] fn test_contains_and_insert() { @@ -98,36 +98,59 @@ fn test_remove_single() { #[bench] fn bench_insert_empty(b: &mut Bencher) { b.iter(|| { - let mut list = TinyList::new(); + let mut list = black_box(TinyList::new()); list.insert(1); + list }) } #[bench] fn bench_insert_one(b: &mut Bencher) { b.iter(|| { - let mut list = TinyList::new_single(0); + let mut list = black_box(TinyList::new_single(0)); list.insert(1); + list }) } +#[bench] +fn bench_contains_empty(b: &mut Bencher) { + b.iter(|| { + black_box(TinyList::new()).contains(&1) + }); +} + +#[bench] +fn bench_contains_unknown(b: &mut Bencher) { + b.iter(|| { + black_box(TinyList::new_single(0)).contains(&1) + }); +} + +#[bench] +fn bench_contains_one(b: &mut Bencher) { + b.iter(|| { + black_box(TinyList::new_single(1)).contains(&1) + }); +} + #[bench] fn bench_remove_empty(b: &mut Bencher) { b.iter(|| { - TinyList::new().remove(&1) + black_box(TinyList::new()).remove(&1) }); } #[bench] fn bench_remove_unknown(b: &mut Bencher) { b.iter(|| { - TinyList::new_single(0).remove(&1) + black_box(TinyList::new_single(0)).remove(&1) }); } #[bench] fn bench_remove_one(b: &mut Bencher) { b.iter(|| { - TinyList::new_single(1).remove(&1) + black_box(TinyList::new_single(1)).remove(&1) }); } From 45f14a8c9026b33dc278000a5fc120e9667806ff Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Wed, 17 Jul 2019 08:19:29 +0200 Subject: [PATCH 2/2] refactor `len` and `contains` to iterate instead of recurse --- src/librustc_data_structures/tiny_list.rs | 56 +++++++---------------- 1 file changed, 16 insertions(+), 40 deletions(-) diff --git a/src/librustc_data_structures/tiny_list.rs b/src/librustc_data_structures/tiny_list.rs index 1c0d9360f25..ea771d9f20f 100644 --- a/src/librustc_data_structures/tiny_list.rs +++ b/src/librustc_data_structures/tiny_list.rs @@ -20,7 +20,6 @@ pub struct TinyList { } impl TinyList { - #[inline] pub fn new() -> TinyList { TinyList { @@ -60,20 +59,24 @@ impl TinyList { #[inline] pub fn contains(&self, data: &T) -> bool { - if let Some(ref head) = self.head { - head.contains(data) - } else { - false + let mut elem = self.head.as_ref(); + while let Some(ref e) = elem { + if &e.data == data { + return true; + } + elem = e.next.as_ref().map(|e| &**e); } + false } #[inline] pub fn len(&self) -> usize { - if let Some(ref head) = self.head { - head.len() - } else { - 0 + let (mut elem, mut count) = (self.head.as_ref(), 0); + while let Some(ref e) = elem { + count += 1; + elem = e.next.as_ref().map(|e| &**e); } + count } } @@ -84,40 +87,13 @@ struct Element { } impl Element { - fn remove_next(&mut self, data: &T) -> bool { - let new_next = if let Some(ref mut next) = self.next { - if next.data != *data { - return next.remove_next(data) - } else { - next.next.take() - } - } else { - return false + let new_next = match self.next { + Some(ref mut next) if next.data == *data => next.next.take(), + Some(ref mut next) => return next.remove_next(data), + None => return false, }; - self.next = new_next; - true } - - fn len(&self) -> usize { - if let Some(ref next) = self.next { - 1 + next.len() - } else { - 1 - } - } - - fn contains(&self, data: &T) -> bool { - if self.data == *data { - return true - } - - if let Some(ref next) = self.next { - next.contains(data) - } else { - false - } - } }