Skip to content

Commit

Permalink
Auto merge of #52997 - llogiq:tiny-list-opt, r=varkor
Browse files Browse the repository at this point in the history
data_structures: make TinyList more readable and optimize remove(_)

also add benchmarks

Before:

```
test tiny_list::test::bench_insert_empty             ... bench:           1 ns/iter (+/- 0)
test tiny_list::test::bench_insert_one               ... bench:          16 ns/iter (+/- 0)
test tiny_list::test::bench_remove_empty             ... bench:           2 ns/iter (+/- 0)
test tiny_list::test::bench_remove_one               ... bench:           6 ns/iter (+/- 0)
test tiny_list::test::bench_remove_unknown           ... bench:           4 ns/iter (+/- 0)
```

After:

```
test tiny_list::test::bench_insert_empty             ... bench:           1 ns/iter (+/- 0)
test tiny_list::test::bench_insert_one               ... bench:          16 ns/iter (+/- 0)
test tiny_list::test::bench_remove_empty             ... bench:           0 ns/iter (+/- 0)
test tiny_list::test::bench_remove_one               ... bench:           3 ns/iter (+/- 0)
test tiny_list::test::bench_remove_unknown           ... bench:           2 ns/iter (+/- 0)
```
  • Loading branch information
bors committed Aug 5, 2018
2 parents 73c7873 + 4471537 commit e9fa9f5
Showing 1 changed file with 49 additions and 32 deletions.
81 changes: 49 additions & 32 deletions src/librustc_data_structures/tiny_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,44 +50,22 @@ impl<T: PartialEq> TinyList<T> {

#[inline]
pub fn insert(&mut self, data: T) {
let current_head = mem::replace(&mut self.head, None);

if let Some(current_head) = current_head {
let current_head = Box::new(current_head);
self.head = Some(Element {
data,
next: Some(current_head)
});
} else {
self.head = Some(Element {
data,
next: None,
})
}
self.head = Some(Element {
data,
next: mem::replace(&mut self.head, None).map(Box::new),
});
}

#[inline]
pub fn remove(&mut self, data: &T) -> bool {
let remove_head = if let Some(ref mut head) = self.head {
if head.data == *data {
Some(mem::replace(&mut head.next, None))
} else {
None
self.head = match self.head {
Some(ref mut head) if head.data == *data => {
mem::replace(&mut head.next, None).map(|x| *x)
}
} else {
return false
Some(ref mut head) => return head.remove_next(data),
None => return false,
};

if let Some(remove_head) = remove_head {
if let Some(next) = remove_head {
self.head = Some(*next);
} else {
self.head = None;
}
return true
}

self.head.as_mut().unwrap().remove_next(data)
true
}

#[inline]
Expand Down Expand Up @@ -156,6 +134,8 @@ impl<T: PartialEq> Element<T> {
#[cfg(test)]
mod test {
use super::*;
extern crate test;
use self::test::Bencher;

#[test]
fn test_contains_and_insert() {
Expand Down Expand Up @@ -248,4 +228,41 @@ mod test {

assert_eq!(list.len(), 0);
}

#[bench]
fn bench_insert_empty(b: &mut Bencher) {
b.iter(|| {
let mut list = TinyList::new();
list.insert(1);
})
}

#[bench]
fn bench_insert_one(b: &mut Bencher) {
b.iter(|| {
let mut list = TinyList::new_single(0);
list.insert(1);
})
}

#[bench]
fn bench_remove_empty(b: &mut Bencher) {
b.iter(|| {
TinyList::new().remove(&1)
});
}

#[bench]
fn bench_remove_unknown(b: &mut Bencher) {
b.iter(|| {
TinyList::new_single(0).remove(&1)
});
}

#[bench]
fn bench_remove_one(b: &mut Bencher) {
b.iter(|| {
TinyList::new_single(1).remove(&1)
});
}
}

0 comments on commit e9fa9f5

Please sign in to comment.