-Version 1.15.1 (2017-02-07)
+Version 1.15.1 (2017-02-08)
===========================
* [Fix IntoIter::as_mut_slice's signature][39466]
pub fn clean(build: &Build) {
rm_rf(build, "tmp".as_ref());
rm_rf(build, &build.out.join("tmp"));
+ rm_rf(build, &build.out.join("dist"));
for host in build.config.host.iter() {
let entries = match build.out.join(host).read_dir() {
name = "collectionstest"
path = "../libcollectionstest/lib.rs"
-# FIXME: need to extract benchmarks to separate crate
-#[[bench]]
-#name = "collectionstest"
-#path = "../libcollectionstest/lib.rs"
+[[bench]]
+name = "collectionsbenches"
+path = "../libcollections/benches/lib.rs"
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+use std::iter::Iterator;
+use std::vec::Vec;
+use std::collections::BTreeMap;
+use std::__rand::{Rng, thread_rng};
+use test::{Bencher, black_box};
+
+macro_rules! map_insert_rand_bench {
+ ($name: ident, $n: expr, $map: ident) => (
+ #[bench]
+ pub fn $name(b: &mut Bencher) {
+ let n: usize = $n;
+ let mut map = $map::new();
+ // setup
+ let mut rng = thread_rng();
+
+ for _ in 0..n {
+ let i = rng.gen::<usize>() % n;
+ map.insert(i, i);
+ }
+
+ // measure
+ b.iter(|| {
+ let k = rng.gen::<usize>() % n;
+ map.insert(k, k);
+ map.remove(&k);
+ });
+ black_box(map);
+ }
+ )
+}
+
+macro_rules! map_insert_seq_bench {
+ ($name: ident, $n: expr, $map: ident) => (
+ #[bench]
+ pub fn $name(b: &mut Bencher) {
+ let mut map = $map::new();
+ let n: usize = $n;
+ // setup
+ for i in 0..n {
+ map.insert(i * 2, i * 2);
+ }
+
+ // measure
+ let mut i = 1;
+ b.iter(|| {
+ map.insert(i, i);
+ map.remove(&i);
+ i = (i + 2) % n;
+ });
+ black_box(map);
+ }
+ )
+}
+
+macro_rules! map_find_rand_bench {
+ ($name: ident, $n: expr, $map: ident) => (
+ #[bench]
+ pub fn $name(b: &mut Bencher) {
+ let mut map = $map::new();
+ let n: usize = $n;
+
+ // setup
+ let mut rng = thread_rng();
+ let mut keys: Vec<_> = (0..n).map(|_| rng.gen::<usize>() % n).collect();
+
+ for &k in &keys {
+ map.insert(k, k);
+ }
+
+ rng.shuffle(&mut keys);
+
+ // measure
+ let mut i = 0;
+ b.iter(|| {
+ let t = map.get(&keys[i]);
+ i = (i + 1) % n;
+ black_box(t);
+ })
+ }
+ )
+}
+
+macro_rules! map_find_seq_bench {
+ ($name: ident, $n: expr, $map: ident) => (
+ #[bench]
+ pub fn $name(b: &mut Bencher) {
+ let mut map = $map::new();
+ let n: usize = $n;
+
+ // setup
+ for i in 0..n {
+ map.insert(i, i);
+ }
+
+ // measure
+ let mut i = 0;
+ b.iter(|| {
+ let x = map.get(&i);
+ i = (i + 1) % n;
+ black_box(x);
+ })
+ }
+ )
+}
+
+map_insert_rand_bench!{insert_rand_100, 100, BTreeMap}
+map_insert_rand_bench!{insert_rand_10_000, 10_000, BTreeMap}
+
+map_insert_seq_bench!{insert_seq_100, 100, BTreeMap}
+map_insert_seq_bench!{insert_seq_10_000, 10_000, BTreeMap}
+
+map_find_rand_bench!{find_rand_100, 100, BTreeMap}
+map_find_rand_bench!{find_rand_10_000, 10_000, BTreeMap}
+
+map_find_seq_bench!{find_seq_100, 100, BTreeMap}
+map_find_seq_bench!{find_seq_10_000, 10_000, BTreeMap}
+
+fn bench_iter(b: &mut Bencher, size: i32) {
+ let mut map = BTreeMap::<i32, i32>::new();
+ let mut rng = thread_rng();
+
+ for _ in 0..size {
+ map.insert(rng.gen(), rng.gen());
+ }
+
+ b.iter(|| {
+ for entry in &map {
+ black_box(entry);
+ }
+ });
+}
+
+#[bench]
+pub fn iter_20(b: &mut Bencher) {
+ bench_iter(b, 20);
+}
+
+#[bench]
+pub fn iter_1000(b: &mut Bencher) {
+ bench_iter(b, 1000);
+}
+
+#[bench]
+pub fn iter_100000(b: &mut Bencher) {
+ bench_iter(b, 100000);
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod map;
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![deny(warnings)]
+
+#![feature(rand)]
+#![feature(test)]
+
+extern crate test;
+
+mod btree;
+mod linked_list;
+mod string;
+mod str;
+mod slice;
+mod vec;
+mod vec_deque;
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::collections::LinkedList;
+use test::Bencher;
+
+#[bench]
+fn bench_collect_into(b: &mut Bencher) {
+ let v = &[0; 64];
+ b.iter(|| {
+ let _: LinkedList<_> = v.iter().cloned().collect();
+ })
+}
+
+#[bench]
+fn bench_push_front(b: &mut Bencher) {
+ let mut m: LinkedList<_> = LinkedList::new();
+ b.iter(|| {
+ m.push_front(0);
+ })
+}
+
+#[bench]
+fn bench_push_back(b: &mut Bencher) {
+ let mut m: LinkedList<_> = LinkedList::new();
+ b.iter(|| {
+ m.push_back(0);
+ })
+}
+
+#[bench]
+fn bench_push_back_pop_back(b: &mut Bencher) {
+ let mut m: LinkedList<_> = LinkedList::new();
+ b.iter(|| {
+ m.push_back(0);
+ m.pop_back();
+ })
+}
+
+#[bench]
+fn bench_push_front_pop_front(b: &mut Bencher) {
+ let mut m: LinkedList<_> = LinkedList::new();
+ b.iter(|| {
+ m.push_front(0);
+ m.pop_front();
+ })
+}
+
+#[bench]
+fn bench_iter(b: &mut Bencher) {
+ let v = &[0; 128];
+ let m: LinkedList<_> = v.iter().cloned().collect();
+ b.iter(|| {
+ assert!(m.iter().count() == 128);
+ })
+}
+#[bench]
+fn bench_iter_mut(b: &mut Bencher) {
+ let v = &[0; 128];
+ let mut m: LinkedList<_> = v.iter().cloned().collect();
+ b.iter(|| {
+ assert!(m.iter_mut().count() == 128);
+ })
+}
+#[bench]
+fn bench_iter_rev(b: &mut Bencher) {
+ let v = &[0; 128];
+ let m: LinkedList<_> = v.iter().cloned().collect();
+ b.iter(|| {
+ assert!(m.iter().rev().count() == 128);
+ })
+}
+#[bench]
+fn bench_iter_mut_rev(b: &mut Bencher) {
+ let v = &[0; 128];
+ let mut m: LinkedList<_> = v.iter().cloned().collect();
+ b.iter(|| {
+ assert!(m.iter_mut().rev().count() == 128);
+ })
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::{mem, ptr};
+use std::__rand::{Rng, thread_rng};
+
+use test::{Bencher, black_box};
+
+#[bench]
+fn iterator(b: &mut Bencher) {
+ // peculiar numbers to stop LLVM from optimising the summation
+ // out.
+ let v: Vec<_> = (0..100).map(|i| i ^ (i << 1) ^ (i >> 1)).collect();
+
+ b.iter(|| {
+ let mut sum = 0;
+ for x in &v {
+ sum += *x;
+ }
+ // sum == 11806, to stop dead code elimination.
+ if sum == 0 {
+ panic!()
+ }
+ })
+}
+
+#[bench]
+fn mut_iterator(b: &mut Bencher) {
+ let mut v = vec![0; 100];
+
+ b.iter(|| {
+ let mut i = 0;
+ for x in &mut v {
+ *x = i;
+ i += 1;
+ }
+ })
+}
+
+#[bench]
+fn concat(b: &mut Bencher) {
+ let xss: Vec<Vec<i32>> = (0..100).map(|i| (0..i).collect()).collect();
+ b.iter(|| {
+ xss.concat();
+ });
+}
+
+#[bench]
+fn join(b: &mut Bencher) {
+ let xss: Vec<Vec<i32>> = (0..100).map(|i| (0..i).collect()).collect();
+ b.iter(|| xss.join(&0));
+}
+
+#[bench]
+fn push(b: &mut Bencher) {
+ let mut vec = Vec::<i32>::new();
+ b.iter(|| {
+ vec.push(0);
+ black_box(&vec);
+ });
+}
+
+#[bench]
+fn starts_with_same_vector(b: &mut Bencher) {
+ let vec: Vec<_> = (0..100).collect();
+ b.iter(|| vec.starts_with(&vec))
+}
+
+#[bench]
+fn starts_with_single_element(b: &mut Bencher) {
+ let vec: Vec<_> = vec![0];
+ b.iter(|| vec.starts_with(&vec))
+}
+
+#[bench]
+fn starts_with_diff_one_element_at_end(b: &mut Bencher) {
+ let vec: Vec<_> = (0..100).collect();
+ let mut match_vec: Vec<_> = (0..99).collect();
+ match_vec.push(0);
+ b.iter(|| vec.starts_with(&match_vec))
+}
+
+#[bench]
+fn ends_with_same_vector(b: &mut Bencher) {
+ let vec: Vec<_> = (0..100).collect();
+ b.iter(|| vec.ends_with(&vec))
+}
+
+#[bench]
+fn ends_with_single_element(b: &mut Bencher) {
+ let vec: Vec<_> = vec![0];
+ b.iter(|| vec.ends_with(&vec))
+}
+
+#[bench]
+fn ends_with_diff_one_element_at_beginning(b: &mut Bencher) {
+ let vec: Vec<_> = (0..100).collect();
+ let mut match_vec: Vec<_> = (0..100).collect();
+ match_vec[0] = 200;
+ b.iter(|| vec.starts_with(&match_vec))
+}
+
+#[bench]
+fn contains_last_element(b: &mut Bencher) {
+ let vec: Vec<_> = (0..100).collect();
+ b.iter(|| vec.contains(&99))
+}
+
+#[bench]
+fn zero_1kb_from_elem(b: &mut Bencher) {
+ b.iter(|| vec![0u8; 1024]);
+}
+
+#[bench]
+fn zero_1kb_set_memory(b: &mut Bencher) {
+ b.iter(|| {
+ let mut v = Vec::<u8>::with_capacity(1024);
+ unsafe {
+ let vp = v.as_mut_ptr();
+ ptr::write_bytes(vp, 0, 1024);
+ v.set_len(1024);
+ }
+ v
+ });
+}
+
+#[bench]
+fn zero_1kb_loop_set(b: &mut Bencher) {
+ b.iter(|| {
+ let mut v = Vec::<u8>::with_capacity(1024);
+ unsafe {
+ v.set_len(1024);
+ }
+ for i in 0..1024 {
+ v[i] = 0;
+ }
+ });
+}
+
+#[bench]
+fn zero_1kb_mut_iter(b: &mut Bencher) {
+ b.iter(|| {
+ let mut v = Vec::<u8>::with_capacity(1024);
+ unsafe {
+ v.set_len(1024);
+ }
+ for x in &mut v {
+ *x = 0;
+ }
+ v
+ });
+}
+
+#[bench]
+fn random_inserts(b: &mut Bencher) {
+ let mut rng = thread_rng();
+ b.iter(|| {
+ let mut v = vec![(0, 0); 30];
+ for _ in 0..100 {
+ let l = v.len();
+ v.insert(rng.gen::<usize>() % (l + 1), (1, 1));
+ }
+ })
+}
+#[bench]
+fn random_removes(b: &mut Bencher) {
+ let mut rng = thread_rng();
+ b.iter(|| {
+ let mut v = vec![(0, 0); 130];
+ for _ in 0..100 {
+ let l = v.len();
+ v.remove(rng.gen::<usize>() % l);
+ }
+ })
+}
+
+fn gen_ascending(len: usize) -> Vec<u64> {
+ (0..len as u64).collect()
+}
+
+fn gen_descending(len: usize) -> Vec<u64> {
+ (0..len as u64).rev().collect()
+}
+
+fn gen_random(len: usize) -> Vec<u64> {
+ let mut rng = thread_rng();
+ rng.gen_iter::<u64>().take(len).collect()
+}
+
+fn gen_mostly_ascending(len: usize) -> Vec<u64> {
+ let mut rng = thread_rng();
+ let mut v = gen_ascending(len);
+ for _ in (0usize..).take_while(|x| x * x <= len) {
+ let x = rng.gen::<usize>() % len;
+ let y = rng.gen::<usize>() % len;
+ v.swap(x, y);
+ }
+ v
+}
+
+fn gen_mostly_descending(len: usize) -> Vec<u64> {
+ let mut rng = thread_rng();
+ let mut v = gen_descending(len);
+ for _ in (0usize..).take_while(|x| x * x <= len) {
+ let x = rng.gen::<usize>() % len;
+ let y = rng.gen::<usize>() % len;
+ v.swap(x, y);
+ }
+ v
+}
+
+fn gen_big_random(len: usize) -> Vec<[u64; 16]> {
+ let mut rng = thread_rng();
+ rng.gen_iter().map(|x| [x; 16]).take(len).collect()
+}
+
+fn gen_big_ascending(len: usize) -> Vec<[u64; 16]> {
+ (0..len as u64).map(|x| [x; 16]).take(len).collect()
+}
+
+fn gen_big_descending(len: usize) -> Vec<[u64; 16]> {
+ (0..len as u64).rev().map(|x| [x; 16]).take(len).collect()
+}
+
+macro_rules! sort_bench {
+ ($name:ident, $gen:expr, $len:expr) => {
+ #[bench]
+ fn $name(b: &mut Bencher) {
+ b.iter(|| $gen($len).sort());
+ b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64;
+ }
+ }
+}
+
+sort_bench!(sort_small_random, gen_random, 10);
+sort_bench!(sort_small_ascending, gen_ascending, 10);
+sort_bench!(sort_small_descending, gen_descending, 10);
+
+sort_bench!(sort_small_big_random, gen_big_random, 10);
+sort_bench!(sort_small_big_ascending, gen_big_ascending, 10);
+sort_bench!(sort_small_big_descending, gen_big_descending, 10);
+
+sort_bench!(sort_medium_random, gen_random, 100);
+sort_bench!(sort_medium_ascending, gen_ascending, 100);
+sort_bench!(sort_medium_descending, gen_descending, 100);
+
+sort_bench!(sort_large_random, gen_random, 10000);
+sort_bench!(sort_large_ascending, gen_ascending, 10000);
+sort_bench!(sort_large_descending, gen_descending, 10000);
+sort_bench!(sort_large_mostly_ascending, gen_mostly_ascending, 10000);
+sort_bench!(sort_large_mostly_descending, gen_mostly_descending, 10000);
+
+sort_bench!(sort_large_big_random, gen_big_random, 10000);
+sort_bench!(sort_large_big_ascending, gen_big_ascending, 10000);
+sort_bench!(sort_large_big_descending, gen_big_descending, 10000);
+
+#[bench]
+fn sort_large_random_expensive(b: &mut Bencher) {
+ let len = 10000;
+ b.iter(|| {
+ let mut v = gen_random(len);
+ let mut count = 0;
+ v.sort_by(|a: &u64, b: &u64| {
+ count += 1;
+ if count % 1_000_000_000 == 0 {
+ panic!("should not happen");
+ }
+ (*a as f64).cos().partial_cmp(&(*b as f64).cos()).unwrap()
+ });
+ black_box(count);
+ });
+ b.bytes = len as u64 * mem::size_of::<u64>() as u64;
+}
\ No newline at end of file
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use test::{Bencher, black_box};
+
+#[bench]
+fn char_iterator(b: &mut Bencher) {
+ let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+
+ b.iter(|| s.chars().count());
+}
+
+#[bench]
+fn char_iterator_for(b: &mut Bencher) {
+ let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+
+ b.iter(|| {
+ for ch in s.chars() { black_box(ch); }
+ });
+}
+
+#[bench]
+fn char_iterator_ascii(b: &mut Bencher) {
+ let s = "Mary had a little lamb, Little lamb
+ Mary had a little lamb, Little lamb
+ Mary had a little lamb, Little lamb
+ Mary had a little lamb, Little lamb
+ Mary had a little lamb, Little lamb
+ Mary had a little lamb, Little lamb";
+
+ b.iter(|| s.chars().count());
+}
+
+#[bench]
+fn char_iterator_rev(b: &mut Bencher) {
+ let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+
+ b.iter(|| s.chars().rev().count());
+}
+
+#[bench]
+fn char_iterator_rev_for(b: &mut Bencher) {
+ let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+
+ b.iter(|| {
+ for ch in s.chars().rev() { black_box(ch); }
+ });
+}
+
+#[bench]
+fn char_indicesator(b: &mut Bencher) {
+ let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+ let len = s.chars().count();
+
+ b.iter(|| assert_eq!(s.char_indices().count(), len));
+}
+
+#[bench]
+fn char_indicesator_rev(b: &mut Bencher) {
+ let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+ let len = s.chars().count();
+
+ b.iter(|| assert_eq!(s.char_indices().rev().count(), len));
+}
+
+#[bench]
+fn split_unicode_ascii(b: &mut Bencher) {
+ let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
+
+ b.iter(|| assert_eq!(s.split('V').count(), 3));
+}
+
+#[bench]
+fn split_ascii(b: &mut Bencher) {
+ let s = "Mary had a little lamb, Little lamb, little-lamb.";
+ let len = s.split(' ').count();
+
+ b.iter(|| assert_eq!(s.split(' ').count(), len));
+}
+
+#[bench]
+fn split_extern_fn(b: &mut Bencher) {
+ let s = "Mary had a little lamb, Little lamb, little-lamb.";
+ let len = s.split(' ').count();
+ fn pred(c: char) -> bool { c == ' ' }
+
+ b.iter(|| assert_eq!(s.split(pred).count(), len));
+}
+
+#[bench]
+fn split_closure(b: &mut Bencher) {
+ let s = "Mary had a little lamb, Little lamb, little-lamb.";
+ let len = s.split(' ').count();
+
+ b.iter(|| assert_eq!(s.split(|c: char| c == ' ').count(), len));
+}
+
+#[bench]
+fn split_slice(b: &mut Bencher) {
+ let s = "Mary had a little lamb, Little lamb, little-lamb.";
+ let len = s.split(' ').count();
+
+ let c: &[char] = &[' '];
+ b.iter(|| assert_eq!(s.split(c).count(), len));
+}
+
+#[bench]
+fn bench_join(b: &mut Bencher) {
+ let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+ let sep = "→";
+ let v = vec![s, s, s, s, s, s, s, s, s, s];
+ b.iter(|| {
+ assert_eq!(v.join(sep).len(), s.len() * 10 + sep.len() * 9);
+ })
+}
+
+#[bench]
+fn bench_contains_short_short(b: &mut Bencher) {
+ let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
+ let needle = "sit";
+
+ b.iter(|| {
+ assert!(haystack.contains(needle));
+ })
+}
+
+#[bench]
+fn bench_contains_short_long(b: &mut Bencher) {
+ let haystack = "\
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
+ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
+eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
+sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
+tempus vel, gravida nec quam.
+
+In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
+sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
+diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
+lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
+eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
+interdum. Curabitur ut nisi justo.
+
+Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
+mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
+lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
+est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
+felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
+ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
+feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
+Aliquam sit amet placerat lorem.
+
+Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
+mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
+Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
+lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
+suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
+cursus accumsan.
+
+Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
+feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
+vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
+leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
+malesuada sollicitudin quam eu fermentum.";
+ let needle = "english";
+
+ b.iter(|| {
+ assert!(!haystack.contains(needle));
+ })
+}
+
+#[bench]
+fn bench_contains_bad_naive(b: &mut Bencher) {
+ let haystack = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ let needle = "aaaaaaaab";
+
+ b.iter(|| {
+ assert!(!haystack.contains(needle));
+ })
+}
+
+#[bench]
+fn bench_contains_equal(b: &mut Bencher) {
+ let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
+ let needle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
+
+ b.iter(|| {
+ assert!(haystack.contains(needle));
+ })
+}
+
+macro_rules! make_test_inner {
+ ($s:ident, $code:expr, $name:ident, $str:expr) => {
+ #[bench]
+ fn $name(bencher: &mut Bencher) {
+ let mut $s = $str;
+ black_box(&mut $s);
+ bencher.iter(|| $code);
+ }
+ }
+}
+
+macro_rules! make_test {
+ ($name:ident, $s:ident, $code:expr) => {
+ mod $name {
+ use test::Bencher;
+ use test::black_box;
+
+ // Short strings: 65 bytes each
+ make_test_inner!($s, $code, short_ascii,
+ "Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!");
+ make_test_inner!($s, $code, short_mixed,
+ "ศไทย中华Việt Nam; Mary had a little lamb, Little lam!");
+ make_test_inner!($s, $code, short_pile_of_poo,
+ "💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!");
+ make_test_inner!($s, $code, long_lorem_ipsum,"\
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
+ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
+eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
+sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
+tempus vel, gravida nec quam.
+
+In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
+sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
+diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
+lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
+eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
+interdum. Curabitur ut nisi justo.
+
+Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
+mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
+lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
+est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
+felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
+ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
+feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
+Aliquam sit amet placerat lorem.
+
+Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
+mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
+Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
+lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
+suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
+cursus accumsan.
+
+Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
+feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
+vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
+leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
+malesuada sollicitudin quam eu fermentum!");
+ }
+ }
+}
+
+make_test!(chars_count, s, s.chars().count());
+
+make_test!(contains_bang_str, s, s.contains("!"));
+make_test!(contains_bang_char, s, s.contains('!'));
+
+make_test!(match_indices_a_str, s, s.match_indices("a").count());
+
+make_test!(split_a_str, s, s.split("a").count());
+
+make_test!(trim_ascii_char, s, {
+ use std::ascii::AsciiExt;
+ s.trim_matches(|c: char| c.is_ascii())
+});
+make_test!(trim_left_ascii_char, s, {
+ use std::ascii::AsciiExt;
+ s.trim_left_matches(|c: char| c.is_ascii())
+});
+make_test!(trim_right_ascii_char, s, {
+ use std::ascii::AsciiExt;
+ s.trim_right_matches(|c: char| c.is_ascii())
+});
+
+make_test!(find_underscore_char, s, s.find('_'));
+make_test!(rfind_underscore_char, s, s.rfind('_'));
+make_test!(find_underscore_str, s, s.find("_"));
+
+make_test!(find_zzz_char, s, s.find('\u{1F4A4}'));
+make_test!(rfind_zzz_char, s, s.rfind('\u{1F4A4}'));
+make_test!(find_zzz_str, s, s.find("\u{1F4A4}"));
+
+make_test!(split_space_char, s, s.split(' ').count());
+make_test!(split_terminator_space_char, s, s.split_terminator(' ').count());
+
+make_test!(splitn_space_char, s, s.splitn(10, ' ').count());
+make_test!(rsplitn_space_char, s, s.rsplitn(10, ' ').count());
+
+make_test!(split_space_str, s, s.split(" ").count());
+make_test!(split_ad_str, s, s.split("ad").count());
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::iter::repeat;
+use test::Bencher;
+
+#[bench]
+fn bench_with_capacity(b: &mut Bencher) {
+ b.iter(|| String::with_capacity(100));
+}
+
+#[bench]
+fn bench_push_str(b: &mut Bencher) {
+ let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+ b.iter(|| {
+ let mut r = String::new();
+ r.push_str(s);
+ });
+}
+
+const REPETITIONS: u64 = 10_000;
+
+#[bench]
+fn bench_push_str_one_byte(b: &mut Bencher) {
+ b.bytes = REPETITIONS;
+ b.iter(|| {
+ let mut r = String::new();
+ for _ in 0..REPETITIONS {
+ r.push_str("a")
+ }
+ });
+}
+
+#[bench]
+fn bench_push_char_one_byte(b: &mut Bencher) {
+ b.bytes = REPETITIONS;
+ b.iter(|| {
+ let mut r = String::new();
+ for _ in 0..REPETITIONS {
+ r.push('a')
+ }
+ });
+}
+
+#[bench]
+fn bench_push_char_two_bytes(b: &mut Bencher) {
+ b.bytes = REPETITIONS * 2;
+ b.iter(|| {
+ let mut r = String::new();
+ for _ in 0..REPETITIONS {
+ r.push('â')
+ }
+ });
+}
+
+#[bench]
+fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
+ let s = b"Hello there, the quick brown fox jumped over the lazy dog! \
+ Lorem ipsum dolor sit amet, consectetur. ";
+
+ assert_eq!(100, s.len());
+ b.iter(|| {
+ let _ = String::from_utf8_lossy(s);
+ });
+}
+
+#[bench]
+fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
+ let s = "𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰".as_bytes();
+ assert_eq!(100, s.len());
+ b.iter(|| {
+ let _ = String::from_utf8_lossy(s);
+ });
+}
+
+#[bench]
+fn from_utf8_lossy_invalid(b: &mut Bencher) {
+ let s = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
+ b.iter(|| {
+ let _ = String::from_utf8_lossy(s);
+ });
+}
+
+#[bench]
+fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
+ let s = repeat(0xf5).take(100).collect::<Vec<_>>();
+ b.iter(|| {
+ let _ = String::from_utf8_lossy(&s);
+ });
+}
+
+#[bench]
+fn bench_exact_size_shrink_to_fit(b: &mut Bencher) {
+ let s = "Hello there, the quick brown fox jumped over the lazy dog! \
+ Lorem ipsum dolor sit amet, consectetur. ";
+ // ensure our operation produces an exact-size string before we benchmark it
+ let mut r = String::with_capacity(s.len());
+ r.push_str(s);
+ assert_eq!(r.len(), r.capacity());
+ b.iter(|| {
+ let mut r = String::with_capacity(s.len());
+ r.push_str(s);
+ r.shrink_to_fit();
+ r
+ });
+}
+
+#[bench]
+fn bench_from_str(b: &mut Bencher) {
+ let s = "Hello there, the quick brown fox jumped over the lazy dog! \
+ Lorem ipsum dolor sit amet, consectetur. ";
+ b.iter(|| String::from(s))
+}
+
+#[bench]
+fn bench_from(b: &mut Bencher) {
+ let s = "Hello there, the quick brown fox jumped over the lazy dog! \
+ Lorem ipsum dolor sit amet, consectetur. ";
+ b.iter(|| String::from(s))
+}
+
+#[bench]
+fn bench_to_string(b: &mut Bencher) {
+ let s = "Hello there, the quick brown fox jumped over the lazy dog! \
+ Lorem ipsum dolor sit amet, consectetur. ";
+ b.iter(|| s.to_string())
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use test::Bencher;
+use std::iter::{FromIterator, repeat};
+
+#[bench]
+fn bench_new(b: &mut Bencher) {
+ b.iter(|| {
+ let v: Vec<u32> = Vec::new();
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), 0);
+ })
+}
+
+fn do_bench_with_capacity(b: &mut Bencher, src_len: usize) {
+ b.bytes = src_len as u64;
+
+ b.iter(|| {
+ let v: Vec<u32> = Vec::with_capacity(src_len);
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), src_len);
+ })
+}
+
+#[bench]
+fn bench_with_capacity_0000(b: &mut Bencher) {
+ do_bench_with_capacity(b, 0)
+}
+
+#[bench]
+fn bench_with_capacity_0010(b: &mut Bencher) {
+ do_bench_with_capacity(b, 10)
+}
+
+#[bench]
+fn bench_with_capacity_0100(b: &mut Bencher) {
+ do_bench_with_capacity(b, 100)
+}
+
+#[bench]
+fn bench_with_capacity_1000(b: &mut Bencher) {
+ do_bench_with_capacity(b, 1000)
+}
+
+fn do_bench_from_fn(b: &mut Bencher, src_len: usize) {
+ b.bytes = src_len as u64;
+
+ b.iter(|| {
+ let dst = (0..src_len).collect::<Vec<_>>();
+ assert_eq!(dst.len(), src_len);
+ assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+ })
+}
+
+#[bench]
+fn bench_from_fn_0000(b: &mut Bencher) {
+ do_bench_from_fn(b, 0)
+}
+
+#[bench]
+fn bench_from_fn_0010(b: &mut Bencher) {
+ do_bench_from_fn(b, 10)
+}
+
+#[bench]
+fn bench_from_fn_0100(b: &mut Bencher) {
+ do_bench_from_fn(b, 100)
+}
+
+#[bench]
+fn bench_from_fn_1000(b: &mut Bencher) {
+ do_bench_from_fn(b, 1000)
+}
+
+fn do_bench_from_elem(b: &mut Bencher, src_len: usize) {
+ b.bytes = src_len as u64;
+
+ b.iter(|| {
+ let dst: Vec<usize> = repeat(5).take(src_len).collect();
+ assert_eq!(dst.len(), src_len);
+ assert!(dst.iter().all(|x| *x == 5));
+ })
+}
+
+#[bench]
+fn bench_from_elem_0000(b: &mut Bencher) {
+ do_bench_from_elem(b, 0)
+}
+
+#[bench]
+fn bench_from_elem_0010(b: &mut Bencher) {
+ do_bench_from_elem(b, 10)
+}
+
+#[bench]
+fn bench_from_elem_0100(b: &mut Bencher) {
+ do_bench_from_elem(b, 100)
+}
+
+#[bench]
+fn bench_from_elem_1000(b: &mut Bencher) {
+ do_bench_from_elem(b, 1000)
+}
+
+fn do_bench_from_slice(b: &mut Bencher, src_len: usize) {
+ let src: Vec<_> = FromIterator::from_iter(0..src_len);
+
+ b.bytes = src_len as u64;
+
+ b.iter(|| {
+ let dst = src.clone()[..].to_vec();
+ assert_eq!(dst.len(), src_len);
+ assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+ });
+}
+
+#[bench]
+fn bench_from_slice_0000(b: &mut Bencher) {
+ do_bench_from_slice(b, 0)
+}
+
+#[bench]
+fn bench_from_slice_0010(b: &mut Bencher) {
+ do_bench_from_slice(b, 10)
+}
+
+#[bench]
+fn bench_from_slice_0100(b: &mut Bencher) {
+ do_bench_from_slice(b, 100)
+}
+
+#[bench]
+fn bench_from_slice_1000(b: &mut Bencher) {
+ do_bench_from_slice(b, 1000)
+}
+
+fn do_bench_from_iter(b: &mut Bencher, src_len: usize) {
+ let src: Vec<_> = FromIterator::from_iter(0..src_len);
+
+ b.bytes = src_len as u64;
+
+ b.iter(|| {
+ let dst: Vec<_> = FromIterator::from_iter(src.clone());
+ assert_eq!(dst.len(), src_len);
+ assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+ });
+}
+
+#[bench]
+fn bench_from_iter_0000(b: &mut Bencher) {
+ do_bench_from_iter(b, 0)
+}
+
+#[bench]
+fn bench_from_iter_0010(b: &mut Bencher) {
+ do_bench_from_iter(b, 10)
+}
+
+#[bench]
+fn bench_from_iter_0100(b: &mut Bencher) {
+ do_bench_from_iter(b, 100)
+}
+
+#[bench]
+fn bench_from_iter_1000(b: &mut Bencher) {
+ do_bench_from_iter(b, 1000)
+}
+
+fn do_bench_extend(b: &mut Bencher, dst_len: usize, src_len: usize) {
+ let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
+ let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
+
+ b.bytes = src_len as u64;
+
+ b.iter(|| {
+ let mut dst = dst.clone();
+ dst.extend(src.clone());
+ assert_eq!(dst.len(), dst_len + src_len);
+ assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+ });
+}
+
+#[bench]
+fn bench_extend_0000_0000(b: &mut Bencher) {
+ do_bench_extend(b, 0, 0)
+}
+
+#[bench]
+fn bench_extend_0000_0010(b: &mut Bencher) {
+ do_bench_extend(b, 0, 10)
+}
+
+#[bench]
+fn bench_extend_0000_0100(b: &mut Bencher) {
+ do_bench_extend(b, 0, 100)
+}
+
+#[bench]
+fn bench_extend_0000_1000(b: &mut Bencher) {
+ do_bench_extend(b, 0, 1000)
+}
+
+#[bench]
+fn bench_extend_0010_0010(b: &mut Bencher) {
+ do_bench_extend(b, 10, 10)
+}
+
+#[bench]
+fn bench_extend_0100_0100(b: &mut Bencher) {
+ do_bench_extend(b, 100, 100)
+}
+
+#[bench]
+fn bench_extend_1000_1000(b: &mut Bencher) {
+ do_bench_extend(b, 1000, 1000)
+}
+
+fn do_bench_push_all(b: &mut Bencher, dst_len: usize, src_len: usize) {
+ let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
+ let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
+
+ b.bytes = src_len as u64;
+
+ b.iter(|| {
+ let mut dst = dst.clone();
+ dst.extend_from_slice(&src);
+ assert_eq!(dst.len(), dst_len + src_len);
+ assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+ });
+}
+
+#[bench]
+fn bench_push_all_0000_0000(b: &mut Bencher) {
+ do_bench_push_all(b, 0, 0)
+}
+
+#[bench]
+fn bench_push_all_0000_0010(b: &mut Bencher) {
+ do_bench_push_all(b, 0, 10)
+}
+
+#[bench]
+fn bench_push_all_0000_0100(b: &mut Bencher) {
+ do_bench_push_all(b, 0, 100)
+}
+
+#[bench]
+fn bench_push_all_0000_1000(b: &mut Bencher) {
+ do_bench_push_all(b, 0, 1000)
+}
+
+#[bench]
+fn bench_push_all_0010_0010(b: &mut Bencher) {
+ do_bench_push_all(b, 10, 10)
+}
+
+#[bench]
+fn bench_push_all_0100_0100(b: &mut Bencher) {
+ do_bench_push_all(b, 100, 100)
+}
+
+#[bench]
+fn bench_push_all_1000_1000(b: &mut Bencher) {
+ do_bench_push_all(b, 1000, 1000)
+}
+
+fn do_bench_push_all_move(b: &mut Bencher, dst_len: usize, src_len: usize) {
+ let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
+ let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
+
+ b.bytes = src_len as u64;
+
+ b.iter(|| {
+ let mut dst = dst.clone();
+ dst.extend(src.clone());
+ assert_eq!(dst.len(), dst_len + src_len);
+ assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+ });
+}
+
+#[bench]
+fn bench_push_all_move_0000_0000(b: &mut Bencher) {
+ do_bench_push_all_move(b, 0, 0)
+}
+
+#[bench]
+fn bench_push_all_move_0000_0010(b: &mut Bencher) {
+ do_bench_push_all_move(b, 0, 10)
+}
+
+#[bench]
+fn bench_push_all_move_0000_0100(b: &mut Bencher) {
+ do_bench_push_all_move(b, 0, 100)
+}
+
+#[bench]
+fn bench_push_all_move_0000_1000(b: &mut Bencher) {
+ do_bench_push_all_move(b, 0, 1000)
+}
+
+#[bench]
+fn bench_push_all_move_0010_0010(b: &mut Bencher) {
+ do_bench_push_all_move(b, 10, 10)
+}
+
+#[bench]
+fn bench_push_all_move_0100_0100(b: &mut Bencher) {
+ do_bench_push_all_move(b, 100, 100)
+}
+
+#[bench]
+fn bench_push_all_move_1000_1000(b: &mut Bencher) {
+ do_bench_push_all_move(b, 1000, 1000)
+}
+
+fn do_bench_clone(b: &mut Bencher, src_len: usize) {
+ let src: Vec<usize> = FromIterator::from_iter(0..src_len);
+
+ b.bytes = src_len as u64;
+
+ b.iter(|| {
+ let dst = src.clone();
+ assert_eq!(dst.len(), src_len);
+ assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+ });
+}
+
+#[bench]
+fn bench_clone_0000(b: &mut Bencher) {
+ do_bench_clone(b, 0)
+}
+
+#[bench]
+fn bench_clone_0010(b: &mut Bencher) {
+ do_bench_clone(b, 10)
+}
+
+#[bench]
+fn bench_clone_0100(b: &mut Bencher) {
+ do_bench_clone(b, 100)
+}
+
+#[bench]
+fn bench_clone_1000(b: &mut Bencher) {
+ do_bench_clone(b, 1000)
+}
+
+fn do_bench_clone_from(b: &mut Bencher, times: usize, dst_len: usize, src_len: usize) {
+ let dst: Vec<_> = FromIterator::from_iter(0..src_len);
+ let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
+
+ b.bytes = (times * src_len) as u64;
+
+ b.iter(|| {
+ let mut dst = dst.clone();
+
+ for _ in 0..times {
+ dst.clone_from(&src);
+
+ assert_eq!(dst.len(), src_len);
+ assert!(dst.iter().enumerate().all(|(i, x)| dst_len + i == *x));
+ }
+ });
+}
+
+#[bench]
+fn bench_clone_from_01_0000_0000(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 0, 0)
+}
+
+#[bench]
+fn bench_clone_from_01_0000_0010(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 0, 10)
+}
+
+#[bench]
+fn bench_clone_from_01_0000_0100(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 0, 100)
+}
+
+#[bench]
+fn bench_clone_from_01_0000_1000(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 0, 1000)
+}
+
+#[bench]
+fn bench_clone_from_01_0010_0010(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 10, 10)
+}
+
+#[bench]
+fn bench_clone_from_01_0100_0100(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 100, 100)
+}
+
+#[bench]
+fn bench_clone_from_01_1000_1000(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 1000, 1000)
+}
+
+#[bench]
+fn bench_clone_from_01_0010_0100(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 10, 100)
+}
+
+#[bench]
+fn bench_clone_from_01_0100_1000(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 100, 1000)
+}
+
+#[bench]
+fn bench_clone_from_01_0010_0000(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 10, 0)
+}
+
+#[bench]
+fn bench_clone_from_01_0100_0010(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 100, 10)
+}
+
+#[bench]
+fn bench_clone_from_01_1000_0100(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 1000, 100)
+}
+
+#[bench]
+fn bench_clone_from_10_0000_0000(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 0, 0)
+}
+
+#[bench]
+fn bench_clone_from_10_0000_0010(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 0, 10)
+}
+
+#[bench]
+fn bench_clone_from_10_0000_0100(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 0, 100)
+}
+
+#[bench]
+fn bench_clone_from_10_0000_1000(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 0, 1000)
+}
+
+#[bench]
+fn bench_clone_from_10_0010_0010(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 10, 10)
+}
+
+#[bench]
+fn bench_clone_from_10_0100_0100(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 100, 100)
+}
+
+#[bench]
+fn bench_clone_from_10_1000_1000(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 1000, 1000)
+}
+
+#[bench]
+fn bench_clone_from_10_0010_0100(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 10, 100)
+}
+
+#[bench]
+fn bench_clone_from_10_0100_1000(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 100, 1000)
+}
+
+#[bench]
+fn bench_clone_from_10_0010_0000(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 10, 0)
+}
+
+#[bench]
+fn bench_clone_from_10_0100_0010(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 100, 10)
+}
+
+#[bench]
+fn bench_clone_from_10_1000_0100(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 1000, 100)
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::collections::VecDeque;
+use test::{Bencher, black_box};
+
+#[bench]
+fn bench_new(b: &mut Bencher) {
+ b.iter(|| {
+ let ring: VecDeque<i32> = VecDeque::new();
+ black_box(ring);
+ })
+}
+
+#[bench]
+fn bench_grow_1025(b: &mut Bencher) {
+ b.iter(|| {
+ let mut deq = VecDeque::new();
+ for i in 0..1025 {
+ deq.push_front(i);
+ }
+ black_box(deq);
+ })
+}
+
+#[bench]
+fn bench_iter_1000(b: &mut Bencher) {
+ let ring: VecDeque<_> = (0..1000).collect();
+
+ b.iter(|| {
+ let mut sum = 0;
+ for &i in &ring {
+ sum += i;
+ }
+ black_box(sum);
+ })
+}
+
+#[bench]
+fn bench_mut_iter_1000(b: &mut Bencher) {
+ let mut ring: VecDeque<_> = (0..1000).collect();
+
+ b.iter(|| {
+ let mut sum = 0;
+ for i in &mut ring {
+ sum += *i;
+ }
+ black_box(sum);
+ })
+}
+++ /dev/null
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-macro_rules! map_insert_rand_bench {
- ($name: ident, $n: expr, $map: ident) => (
- #[bench]
- pub fn $name(b: &mut ::test::Bencher) {
- use std::__rand::{thread_rng, Rng};
- use test::black_box;
-
- let n: usize = $n;
- let mut map = $map::new();
- // setup
- let mut rng = thread_rng();
-
- for _ in 0..n {
- let i = rng.gen::<usize>() % n;
- map.insert(i, i);
- }
-
- // measure
- b.iter(|| {
- let k = rng.gen::<usize>() % n;
- map.insert(k, k);
- map.remove(&k);
- });
- black_box(map);
- }
- )
-}
-
-macro_rules! map_insert_seq_bench {
- ($name: ident, $n: expr, $map: ident) => (
- #[bench]
- pub fn $name(b: &mut ::test::Bencher) {
- use test::black_box;
-
- let mut map = $map::new();
- let n: usize = $n;
- // setup
- for i in 0..n {
- map.insert(i * 2, i * 2);
- }
-
- // measure
- let mut i = 1;
- b.iter(|| {
- map.insert(i, i);
- map.remove(&i);
- i = (i + 2) % n;
- });
- black_box(map);
- }
- )
-}
-
-macro_rules! map_find_rand_bench {
- ($name: ident, $n: expr, $map: ident) => (
- #[bench]
- pub fn $name(b: &mut ::test::Bencher) {
- use std::iter::Iterator;
- use std::__rand::{thread_rng, Rng};
- use std::vec::Vec;
- use test::black_box;
-
- let mut map = $map::new();
- let n: usize = $n;
-
- // setup
- let mut rng = thread_rng();
- let mut keys: Vec<_> = (0..n).map(|_| rng.gen::<usize>() % n).collect();
-
- for &k in &keys {
- map.insert(k, k);
- }
-
- rng.shuffle(&mut keys);
-
- // measure
- let mut i = 0;
- b.iter(|| {
- let t = map.get(&keys[i]);
- i = (i + 1) % n;
- black_box(t);
- })
- }
- )
-}
-
-macro_rules! map_find_seq_bench {
- ($name: ident, $n: expr, $map: ident) => (
- #[bench]
- pub fn $name(b: &mut ::test::Bencher) {
- use test::black_box;
-
- let mut map = $map::new();
- let n: usize = $n;
-
- // setup
- for i in 0..n {
- map.insert(i, i);
- }
-
- // measure
- let mut i = 0;
- b.iter(|| {
- let x = map.get(&i);
- i = (i + 1) % n;
- black_box(x);
- })
- }
- )
-}
assert!(map.into_iter().eq(data.clone().into_iter().filter(|x| x.0 < key)));
assert!(right.into_iter().eq(data.into_iter().filter(|x| x.0 >= key)));
}
-
-mod bench {
- use std::collections::BTreeMap;
- use std::__rand::{Rng, thread_rng};
-
- use test::{Bencher, black_box};
-
- map_insert_rand_bench!{insert_rand_100, 100, BTreeMap}
- map_insert_rand_bench!{insert_rand_10_000, 10_000, BTreeMap}
-
- map_insert_seq_bench!{insert_seq_100, 100, BTreeMap}
- map_insert_seq_bench!{insert_seq_10_000, 10_000, BTreeMap}
-
- map_find_rand_bench!{find_rand_100, 100, BTreeMap}
- map_find_rand_bench!{find_rand_10_000, 10_000, BTreeMap}
-
- map_find_seq_bench!{find_seq_100, 100, BTreeMap}
- map_find_seq_bench!{find_seq_10_000, 10_000, BTreeMap}
-
- fn bench_iter(b: &mut Bencher, size: i32) {
- let mut map = BTreeMap::<i32, i32>::new();
- let mut rng = thread_rng();
-
- for _ in 0..size {
- map.insert(rng.gen(), rng.gen());
- }
-
- b.iter(|| {
- for entry in &map {
- black_box(entry);
- }
- });
- }
-
- #[bench]
- pub fn iter_20(b: &mut Bencher) {
- bench_iter(b, 20);
- }
-
- #[bench]
- pub fn iter_1000(b: &mut Bencher) {
- bench_iter(b, 1000);
- }
-
- #[bench]
- pub fn iter_100000(b: &mut Bencher) {
- bench_iter(b, 100000);
- }
-}
use std::hash::{Hash, Hasher};
use std::collections::hash_map::DefaultHasher;
-#[cfg(test)]
-#[macro_use]
-mod bench;
-
mod binary_heap;
mod btree;
mod cow_str;
use std::collections::LinkedList;
-use test;
-
#[test]
fn test_basic() {
let mut m = LinkedList::<Box<_>>::new();
assert!(a.iter().eq(&[1, 2, 3, 4, 5, 6, 7]));
}
-#[bench]
-fn bench_collect_into(b: &mut test::Bencher) {
- let v = &[0; 64];
- b.iter(|| {
- let _: LinkedList<_> = v.iter().cloned().collect();
- })
-}
-
-#[bench]
-fn bench_push_front(b: &mut test::Bencher) {
- let mut m: LinkedList<_> = LinkedList::new();
- b.iter(|| {
- m.push_front(0);
- })
-}
-
-#[bench]
-fn bench_push_back(b: &mut test::Bencher) {
- let mut m: LinkedList<_> = LinkedList::new();
- b.iter(|| {
- m.push_back(0);
- })
-}
-
-#[bench]
-fn bench_push_back_pop_back(b: &mut test::Bencher) {
- let mut m: LinkedList<_> = LinkedList::new();
- b.iter(|| {
- m.push_back(0);
- m.pop_back();
- })
-}
-
-#[bench]
-fn bench_push_front_pop_front(b: &mut test::Bencher) {
- let mut m: LinkedList<_> = LinkedList::new();
- b.iter(|| {
- m.push_front(0);
- m.pop_front();
- })
-}
-
-#[bench]
-fn bench_iter(b: &mut test::Bencher) {
- let v = &[0; 128];
- let m: LinkedList<_> = v.iter().cloned().collect();
- b.iter(|| {
- assert!(m.iter().count() == 128);
- })
-}
-#[bench]
-fn bench_iter_mut(b: &mut test::Bencher) {
- let v = &[0; 128];
- let mut m: LinkedList<_> = v.iter().cloned().collect();
- b.iter(|| {
- assert!(m.iter_mut().count() == 128);
- })
-}
-#[bench]
-fn bench_iter_rev(b: &mut test::Bencher) {
- let v = &[0; 128];
- let m: LinkedList<_> = v.iter().cloned().collect();
- b.iter(|| {
- assert!(m.iter().rev().count() == 128);
- })
-}
-#[bench]
-fn bench_iter_mut_rev(b: &mut test::Bencher) {
- let v = &[0; 128];
- let mut m: LinkedList<_> = v.iter().cloned().collect();
- b.iter(|| {
- assert!(m.iter_mut().rev().count() == 128);
- })
-}
-
#[test]
fn test_contains() {
let mut l = LinkedList::new();
let mut dst = [0; 3];
dst.copy_from_slice(&src);
}
-
-mod bench {
- use std::{mem, ptr};
- use std::__rand::{Rng, thread_rng};
-
- use test::{Bencher, black_box};
-
- #[bench]
- fn iterator(b: &mut Bencher) {
- // peculiar numbers to stop LLVM from optimising the summation
- // out.
- let v: Vec<_> = (0..100).map(|i| i ^ (i << 1) ^ (i >> 1)).collect();
-
- b.iter(|| {
- let mut sum = 0;
- for x in &v {
- sum += *x;
- }
- // sum == 11806, to stop dead code elimination.
- if sum == 0 {
- panic!()
- }
- })
- }
-
- #[bench]
- fn mut_iterator(b: &mut Bencher) {
- let mut v = vec![0; 100];
-
- b.iter(|| {
- let mut i = 0;
- for x in &mut v {
- *x = i;
- i += 1;
- }
- })
- }
-
- #[bench]
- fn concat(b: &mut Bencher) {
- let xss: Vec<Vec<i32>> = (0..100).map(|i| (0..i).collect()).collect();
- b.iter(|| {
- xss.concat();
- });
- }
-
- #[bench]
- fn join(b: &mut Bencher) {
- let xss: Vec<Vec<i32>> = (0..100).map(|i| (0..i).collect()).collect();
- b.iter(|| xss.join(&0));
- }
-
- #[bench]
- fn push(b: &mut Bencher) {
- let mut vec = Vec::<i32>::new();
- b.iter(|| {
- vec.push(0);
- black_box(&vec);
- });
- }
-
- #[bench]
- fn starts_with_same_vector(b: &mut Bencher) {
- let vec: Vec<_> = (0..100).collect();
- b.iter(|| vec.starts_with(&vec))
- }
-
- #[bench]
- fn starts_with_single_element(b: &mut Bencher) {
- let vec: Vec<_> = vec![0];
- b.iter(|| vec.starts_with(&vec))
- }
-
- #[bench]
- fn starts_with_diff_one_element_at_end(b: &mut Bencher) {
- let vec: Vec<_> = (0..100).collect();
- let mut match_vec: Vec<_> = (0..99).collect();
- match_vec.push(0);
- b.iter(|| vec.starts_with(&match_vec))
- }
-
- #[bench]
- fn ends_with_same_vector(b: &mut Bencher) {
- let vec: Vec<_> = (0..100).collect();
- b.iter(|| vec.ends_with(&vec))
- }
-
- #[bench]
- fn ends_with_single_element(b: &mut Bencher) {
- let vec: Vec<_> = vec![0];
- b.iter(|| vec.ends_with(&vec))
- }
-
- #[bench]
- fn ends_with_diff_one_element_at_beginning(b: &mut Bencher) {
- let vec: Vec<_> = (0..100).collect();
- let mut match_vec: Vec<_> = (0..100).collect();
- match_vec[0] = 200;
- b.iter(|| vec.starts_with(&match_vec))
- }
-
- #[bench]
- fn contains_last_element(b: &mut Bencher) {
- let vec: Vec<_> = (0..100).collect();
- b.iter(|| vec.contains(&99))
- }
-
- #[bench]
- fn zero_1kb_from_elem(b: &mut Bencher) {
- b.iter(|| vec![0u8; 1024]);
- }
-
- #[bench]
- fn zero_1kb_set_memory(b: &mut Bencher) {
- b.iter(|| {
- let mut v = Vec::<u8>::with_capacity(1024);
- unsafe {
- let vp = v.as_mut_ptr();
- ptr::write_bytes(vp, 0, 1024);
- v.set_len(1024);
- }
- v
- });
- }
-
- #[bench]
- fn zero_1kb_loop_set(b: &mut Bencher) {
- b.iter(|| {
- let mut v = Vec::<u8>::with_capacity(1024);
- unsafe {
- v.set_len(1024);
- }
- for i in 0..1024 {
- v[i] = 0;
- }
- });
- }
-
- #[bench]
- fn zero_1kb_mut_iter(b: &mut Bencher) {
- b.iter(|| {
- let mut v = Vec::<u8>::with_capacity(1024);
- unsafe {
- v.set_len(1024);
- }
- for x in &mut v {
- *x = 0;
- }
- v
- });
- }
-
- #[bench]
- fn random_inserts(b: &mut Bencher) {
- let mut rng = thread_rng();
- b.iter(|| {
- let mut v = vec![(0, 0); 30];
- for _ in 0..100 {
- let l = v.len();
- v.insert(rng.gen::<usize>() % (l + 1), (1, 1));
- }
- })
- }
- #[bench]
- fn random_removes(b: &mut Bencher) {
- let mut rng = thread_rng();
- b.iter(|| {
- let mut v = vec![(0, 0); 130];
- for _ in 0..100 {
- let l = v.len();
- v.remove(rng.gen::<usize>() % l);
- }
- })
- }
-
- fn gen_ascending(len: usize) -> Vec<u64> {
- (0..len as u64).collect()
- }
-
- fn gen_descending(len: usize) -> Vec<u64> {
- (0..len as u64).rev().collect()
- }
-
- fn gen_random(len: usize) -> Vec<u64> {
- let mut rng = thread_rng();
- rng.gen_iter::<u64>().take(len).collect()
- }
-
- fn gen_mostly_ascending(len: usize) -> Vec<u64> {
- let mut rng = thread_rng();
- let mut v = gen_ascending(len);
- for _ in (0usize..).take_while(|x| x * x <= len) {
- let x = rng.gen::<usize>() % len;
- let y = rng.gen::<usize>() % len;
- v.swap(x, y);
- }
- v
- }
-
- fn gen_mostly_descending(len: usize) -> Vec<u64> {
- let mut rng = thread_rng();
- let mut v = gen_descending(len);
- for _ in (0usize..).take_while(|x| x * x <= len) {
- let x = rng.gen::<usize>() % len;
- let y = rng.gen::<usize>() % len;
- v.swap(x, y);
- }
- v
- }
-
- fn gen_big_random(len: usize) -> Vec<[u64; 16]> {
- let mut rng = thread_rng();
- rng.gen_iter().map(|x| [x; 16]).take(len).collect()
- }
-
- fn gen_big_ascending(len: usize) -> Vec<[u64; 16]> {
- (0..len as u64).map(|x| [x; 16]).take(len).collect()
- }
-
- fn gen_big_descending(len: usize) -> Vec<[u64; 16]> {
- (0..len as u64).rev().map(|x| [x; 16]).take(len).collect()
- }
-
- macro_rules! sort_bench {
- ($name:ident, $gen:expr, $len:expr) => {
- #[bench]
- fn $name(b: &mut Bencher) {
- b.iter(|| $gen($len).sort());
- b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64;
- }
- }
- }
-
- sort_bench!(sort_small_random, gen_random, 10);
- sort_bench!(sort_small_ascending, gen_ascending, 10);
- sort_bench!(sort_small_descending, gen_descending, 10);
-
- sort_bench!(sort_small_big_random, gen_big_random, 10);
- sort_bench!(sort_small_big_ascending, gen_big_ascending, 10);
- sort_bench!(sort_small_big_descending, gen_big_descending, 10);
-
- sort_bench!(sort_medium_random, gen_random, 100);
- sort_bench!(sort_medium_ascending, gen_ascending, 100);
- sort_bench!(sort_medium_descending, gen_descending, 100);
-
- sort_bench!(sort_large_random, gen_random, 10000);
- sort_bench!(sort_large_ascending, gen_ascending, 10000);
- sort_bench!(sort_large_descending, gen_descending, 10000);
- sort_bench!(sort_large_mostly_ascending, gen_mostly_ascending, 10000);
- sort_bench!(sort_large_mostly_descending, gen_mostly_descending, 10000);
-
- sort_bench!(sort_large_big_random, gen_big_random, 10000);
- sort_bench!(sort_large_big_ascending, gen_big_ascending, 10000);
- sort_bench!(sort_large_big_descending, gen_big_descending, 10000);
-
- #[bench]
- fn sort_large_random_expensive(b: &mut Bencher) {
- let len = 10000;
- b.iter(|| {
- let mut v = gen_random(len);
- let mut count = 0;
- v.sort_by(|a: &u64, b: &u64| {
- count += 1;
- if count % 1_000_000_000 == 0 {
- panic!("should not happen");
- }
- (*a as f64).cos().partial_cmp(&(*b as f64).cos()).unwrap()
- });
- black_box(count);
- });
- b.bytes = len as u64 * mem::size_of::<u64>() as u64;
- }
-}
foo::<&str>("x");
}
-
-mod bench {
- use test::{Bencher, black_box};
-
- #[bench]
- fn char_iterator(b: &mut Bencher) {
- let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-
- b.iter(|| s.chars().count());
- }
-
- #[bench]
- fn char_iterator_for(b: &mut Bencher) {
- let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-
- b.iter(|| {
- for ch in s.chars() { black_box(ch); }
- });
- }
-
- #[bench]
- fn char_iterator_ascii(b: &mut Bencher) {
- let s = "Mary had a little lamb, Little lamb
- Mary had a little lamb, Little lamb
- Mary had a little lamb, Little lamb
- Mary had a little lamb, Little lamb
- Mary had a little lamb, Little lamb
- Mary had a little lamb, Little lamb";
-
- b.iter(|| s.chars().count());
- }
-
- #[bench]
- fn char_iterator_rev(b: &mut Bencher) {
- let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-
- b.iter(|| s.chars().rev().count());
- }
-
- #[bench]
- fn char_iterator_rev_for(b: &mut Bencher) {
- let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-
- b.iter(|| {
- for ch in s.chars().rev() { black_box(ch); }
- });
- }
-
- #[bench]
- fn char_indicesator(b: &mut Bencher) {
- let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
- let len = s.chars().count();
-
- b.iter(|| assert_eq!(s.char_indices().count(), len));
- }
-
- #[bench]
- fn char_indicesator_rev(b: &mut Bencher) {
- let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
- let len = s.chars().count();
-
- b.iter(|| assert_eq!(s.char_indices().rev().count(), len));
- }
-
- #[bench]
- fn split_unicode_ascii(b: &mut Bencher) {
- let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
-
- b.iter(|| assert_eq!(s.split('V').count(), 3));
- }
-
- #[bench]
- fn split_ascii(b: &mut Bencher) {
- let s = "Mary had a little lamb, Little lamb, little-lamb.";
- let len = s.split(' ').count();
-
- b.iter(|| assert_eq!(s.split(' ').count(), len));
- }
-
- #[bench]
- fn split_extern_fn(b: &mut Bencher) {
- let s = "Mary had a little lamb, Little lamb, little-lamb.";
- let len = s.split(' ').count();
- fn pred(c: char) -> bool { c == ' ' }
-
- b.iter(|| assert_eq!(s.split(pred).count(), len));
- }
-
- #[bench]
- fn split_closure(b: &mut Bencher) {
- let s = "Mary had a little lamb, Little lamb, little-lamb.";
- let len = s.split(' ').count();
-
- b.iter(|| assert_eq!(s.split(|c: char| c == ' ').count(), len));
- }
-
- #[bench]
- fn split_slice(b: &mut Bencher) {
- let s = "Mary had a little lamb, Little lamb, little-lamb.";
- let len = s.split(' ').count();
-
- let c: &[char] = &[' '];
- b.iter(|| assert_eq!(s.split(c).count(), len));
- }
-
- #[bench]
- fn bench_join(b: &mut Bencher) {
- let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
- let sep = "→";
- let v = vec![s, s, s, s, s, s, s, s, s, s];
- b.iter(|| {
- assert_eq!(v.join(sep).len(), s.len() * 10 + sep.len() * 9);
- })
- }
-
- #[bench]
- fn bench_contains_short_short(b: &mut Bencher) {
- let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
- let needle = "sit";
-
- b.iter(|| {
- assert!(haystack.contains(needle));
- })
- }
-
- #[bench]
- fn bench_contains_short_long(b: &mut Bencher) {
- let haystack = "\
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
-ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
-eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
-sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
-tempus vel, gravida nec quam.
-
-In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
-sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
-diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
-lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
-eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
-interdum. Curabitur ut nisi justo.
-
-Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
-mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
-lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
-est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
-felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
-ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
-feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
-Aliquam sit amet placerat lorem.
-
-Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
-mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
-Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
-lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
-suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
-cursus accumsan.
-
-Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
-feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
-vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
-leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
-malesuada sollicitudin quam eu fermentum.";
- let needle = "english";
-
- b.iter(|| {
- assert!(!haystack.contains(needle));
- })
- }
-
- #[bench]
- fn bench_contains_bad_naive(b: &mut Bencher) {
- let haystack = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
- let needle = "aaaaaaaab";
-
- b.iter(|| {
- assert!(!haystack.contains(needle));
- })
- }
-
- #[bench]
- fn bench_contains_equal(b: &mut Bencher) {
- let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
- let needle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
-
- b.iter(|| {
- assert!(haystack.contains(needle));
- })
- }
-
- macro_rules! make_test_inner {
- ($s:ident, $code:expr, $name:ident, $str:expr) => {
- #[bench]
- fn $name(bencher: &mut Bencher) {
- let mut $s = $str;
- black_box(&mut $s);
- bencher.iter(|| $code);
- }
- }
- }
-
- macro_rules! make_test {
- ($name:ident, $s:ident, $code:expr) => {
- mod $name {
- use test::Bencher;
- use test::black_box;
-
- // Short strings: 65 bytes each
- make_test_inner!($s, $code, short_ascii,
- "Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!");
- make_test_inner!($s, $code, short_mixed,
- "ศไทย中华Việt Nam; Mary had a little lamb, Little lam!");
- make_test_inner!($s, $code, short_pile_of_poo,
- "💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!");
- make_test_inner!($s, $code, long_lorem_ipsum,"\
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
-ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
-eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
-sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
-tempus vel, gravida nec quam.
-
-In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
-sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
-diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
-lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
-eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
-interdum. Curabitur ut nisi justo.
-
-Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
-mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
-lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
-est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
-felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
-ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
-feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
-Aliquam sit amet placerat lorem.
-
-Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
-mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
-Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
-lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
-suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
-cursus accumsan.
-
-Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
-feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
-vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
-leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
-malesuada sollicitudin quam eu fermentum!");
- }
- }
- }
-
- make_test!(chars_count, s, s.chars().count());
-
- make_test!(contains_bang_str, s, s.contains("!"));
- make_test!(contains_bang_char, s, s.contains('!'));
-
- make_test!(match_indices_a_str, s, s.match_indices("a").count());
-
- make_test!(split_a_str, s, s.split("a").count());
-
- make_test!(trim_ascii_char, s, {
- use std::ascii::AsciiExt;
- s.trim_matches(|c: char| c.is_ascii())
- });
- make_test!(trim_left_ascii_char, s, {
- use std::ascii::AsciiExt;
- s.trim_left_matches(|c: char| c.is_ascii())
- });
- make_test!(trim_right_ascii_char, s, {
- use std::ascii::AsciiExt;
- s.trim_right_matches(|c: char| c.is_ascii())
- });
-
- make_test!(find_underscore_char, s, s.find('_'));
- make_test!(rfind_underscore_char, s, s.rfind('_'));
- make_test!(find_underscore_str, s, s.find("_"));
-
- make_test!(find_zzz_char, s, s.find('\u{1F4A4}'));
- make_test!(rfind_zzz_char, s, s.rfind('\u{1F4A4}'));
- make_test!(find_zzz_str, s, s.find("\u{1F4A4}"));
-
- make_test!(split_space_char, s, s.split(' ').count());
- make_test!(split_terminator_space_char, s, s.split_terminator(' ').count());
-
- make_test!(splitn_space_char, s, s.splitn(10, ' ').count());
- make_test!(rsplitn_space_char, s, s.rsplitn(10, ' ').count());
-
- make_test!(split_space_str, s, s.split(" ").count());
- make_test!(split_ad_str, s, s.split("ad").count());
-}
// except according to those terms.
use std::borrow::Cow;
-use std::iter::repeat;
-
-use test::Bencher;
pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
fn into_cow(self) -> Cow<'a, B>;
let ys = xs.into_boxed_str();
assert_eq!(&*ys, "hello my name is bob");
}
-
-#[bench]
-fn bench_with_capacity(b: &mut Bencher) {
- b.iter(|| String::with_capacity(100));
-}
-
-#[bench]
-fn bench_push_str(b: &mut Bencher) {
- let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
- b.iter(|| {
- let mut r = String::new();
- r.push_str(s);
- });
-}
-
-const REPETITIONS: u64 = 10_000;
-
-#[bench]
-fn bench_push_str_one_byte(b: &mut Bencher) {
- b.bytes = REPETITIONS;
- b.iter(|| {
- let mut r = String::new();
- for _ in 0..REPETITIONS {
- r.push_str("a")
- }
- });
-}
-
-#[bench]
-fn bench_push_char_one_byte(b: &mut Bencher) {
- b.bytes = REPETITIONS;
- b.iter(|| {
- let mut r = String::new();
- for _ in 0..REPETITIONS {
- r.push('a')
- }
- });
-}
-
-#[bench]
-fn bench_push_char_two_bytes(b: &mut Bencher) {
- b.bytes = REPETITIONS * 2;
- b.iter(|| {
- let mut r = String::new();
- for _ in 0..REPETITIONS {
- r.push('â')
- }
- });
-}
-
-#[bench]
-fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
- let s = b"Hello there, the quick brown fox jumped over the lazy dog! \
- Lorem ipsum dolor sit amet, consectetur. ";
-
- assert_eq!(100, s.len());
- b.iter(|| {
- let _ = String::from_utf8_lossy(s);
- });
-}
-
-#[bench]
-fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
- let s = "𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰".as_bytes();
- assert_eq!(100, s.len());
- b.iter(|| {
- let _ = String::from_utf8_lossy(s);
- });
-}
-
-#[bench]
-fn from_utf8_lossy_invalid(b: &mut Bencher) {
- let s = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
- b.iter(|| {
- let _ = String::from_utf8_lossy(s);
- });
-}
-
-#[bench]
-fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
- let s = repeat(0xf5).take(100).collect::<Vec<_>>();
- b.iter(|| {
- let _ = String::from_utf8_lossy(&s);
- });
-}
-
-#[bench]
-fn bench_exact_size_shrink_to_fit(b: &mut Bencher) {
- let s = "Hello there, the quick brown fox jumped over the lazy dog! \
- Lorem ipsum dolor sit amet, consectetur. ";
- // ensure our operation produces an exact-size string before we benchmark it
- let mut r = String::with_capacity(s.len());
- r.push_str(s);
- assert_eq!(r.len(), r.capacity());
- b.iter(|| {
- let mut r = String::with_capacity(s.len());
- r.push_str(s);
- r.shrink_to_fit();
- r
- });
-}
-
-#[bench]
-fn bench_from_str(b: &mut Bencher) {
- let s = "Hello there, the quick brown fox jumped over the lazy dog! \
- Lorem ipsum dolor sit amet, consectetur. ";
- b.iter(|| String::from(s))
-}
-
-#[bench]
-fn bench_from(b: &mut Bencher) {
- let s = "Hello there, the quick brown fox jumped over the lazy dog! \
- Lorem ipsum dolor sit amet, consectetur. ";
- b.iter(|| String::from(s))
-}
-
-#[bench]
-fn bench_to_string(b: &mut Bencher) {
- let s = "Hello there, the quick brown fox jumped over the lazy dog! \
- Lorem ipsum dolor sit amet, consectetur. ";
- b.iter(|| s.to_string())
-}
use std::ascii::AsciiExt;
use std::borrow::Cow;
-use std::iter::{FromIterator, repeat};
use std::mem::size_of;
use std::panic;
use std::vec::{Drain, IntoIter};
-use test::Bencher;
-
struct DropCounter<'a> {
count: &'a mut u32,
}
let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { vec.place_back() <- mkpanic(); }));
assert_eq!(vec.len(), 3);
}
-
-#[bench]
-fn bench_new(b: &mut Bencher) {
- b.iter(|| {
- let v: Vec<u32> = Vec::new();
- assert_eq!(v.len(), 0);
- assert_eq!(v.capacity(), 0);
- })
-}
-
-fn do_bench_with_capacity(b: &mut Bencher, src_len: usize) {
- b.bytes = src_len as u64;
-
- b.iter(|| {
- let v: Vec<u32> = Vec::with_capacity(src_len);
- assert_eq!(v.len(), 0);
- assert_eq!(v.capacity(), src_len);
- })
-}
-
-#[bench]
-fn bench_with_capacity_0000(b: &mut Bencher) {
- do_bench_with_capacity(b, 0)
-}
-
-#[bench]
-fn bench_with_capacity_0010(b: &mut Bencher) {
- do_bench_with_capacity(b, 10)
-}
-
-#[bench]
-fn bench_with_capacity_0100(b: &mut Bencher) {
- do_bench_with_capacity(b, 100)
-}
-
-#[bench]
-fn bench_with_capacity_1000(b: &mut Bencher) {
- do_bench_with_capacity(b, 1000)
-}
-
-fn do_bench_from_fn(b: &mut Bencher, src_len: usize) {
- b.bytes = src_len as u64;
-
- b.iter(|| {
- let dst = (0..src_len).collect::<Vec<_>>();
- assert_eq!(dst.len(), src_len);
- assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
- })
-}
-
-#[bench]
-fn bench_from_fn_0000(b: &mut Bencher) {
- do_bench_from_fn(b, 0)
-}
-
-#[bench]
-fn bench_from_fn_0010(b: &mut Bencher) {
- do_bench_from_fn(b, 10)
-}
-
-#[bench]
-fn bench_from_fn_0100(b: &mut Bencher) {
- do_bench_from_fn(b, 100)
-}
-
-#[bench]
-fn bench_from_fn_1000(b: &mut Bencher) {
- do_bench_from_fn(b, 1000)
-}
-
-fn do_bench_from_elem(b: &mut Bencher, src_len: usize) {
- b.bytes = src_len as u64;
-
- b.iter(|| {
- let dst: Vec<usize> = repeat(5).take(src_len).collect();
- assert_eq!(dst.len(), src_len);
- assert!(dst.iter().all(|x| *x == 5));
- })
-}
-
-#[bench]
-fn bench_from_elem_0000(b: &mut Bencher) {
- do_bench_from_elem(b, 0)
-}
-
-#[bench]
-fn bench_from_elem_0010(b: &mut Bencher) {
- do_bench_from_elem(b, 10)
-}
-
-#[bench]
-fn bench_from_elem_0100(b: &mut Bencher) {
- do_bench_from_elem(b, 100)
-}
-
-#[bench]
-fn bench_from_elem_1000(b: &mut Bencher) {
- do_bench_from_elem(b, 1000)
-}
-
-fn do_bench_from_slice(b: &mut Bencher, src_len: usize) {
- let src: Vec<_> = FromIterator::from_iter(0..src_len);
-
- b.bytes = src_len as u64;
-
- b.iter(|| {
- let dst = src.clone()[..].to_vec();
- assert_eq!(dst.len(), src_len);
- assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
- });
-}
-
-#[bench]
-fn bench_from_slice_0000(b: &mut Bencher) {
- do_bench_from_slice(b, 0)
-}
-
-#[bench]
-fn bench_from_slice_0010(b: &mut Bencher) {
- do_bench_from_slice(b, 10)
-}
-
-#[bench]
-fn bench_from_slice_0100(b: &mut Bencher) {
- do_bench_from_slice(b, 100)
-}
-
-#[bench]
-fn bench_from_slice_1000(b: &mut Bencher) {
- do_bench_from_slice(b, 1000)
-}
-
-fn do_bench_from_iter(b: &mut Bencher, src_len: usize) {
- let src: Vec<_> = FromIterator::from_iter(0..src_len);
-
- b.bytes = src_len as u64;
-
- b.iter(|| {
- let dst: Vec<_> = FromIterator::from_iter(src.clone());
- assert_eq!(dst.len(), src_len);
- assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
- });
-}
-
-#[bench]
-fn bench_from_iter_0000(b: &mut Bencher) {
- do_bench_from_iter(b, 0)
-}
-
-#[bench]
-fn bench_from_iter_0010(b: &mut Bencher) {
- do_bench_from_iter(b, 10)
-}
-
-#[bench]
-fn bench_from_iter_0100(b: &mut Bencher) {
- do_bench_from_iter(b, 100)
-}
-
-#[bench]
-fn bench_from_iter_1000(b: &mut Bencher) {
- do_bench_from_iter(b, 1000)
-}
-
-fn do_bench_extend(b: &mut Bencher, dst_len: usize, src_len: usize) {
- let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
- let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
-
- b.bytes = src_len as u64;
-
- b.iter(|| {
- let mut dst = dst.clone();
- dst.extend(src.clone());
- assert_eq!(dst.len(), dst_len + src_len);
- assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
- });
-}
-
-#[bench]
-fn bench_extend_0000_0000(b: &mut Bencher) {
- do_bench_extend(b, 0, 0)
-}
-
-#[bench]
-fn bench_extend_0000_0010(b: &mut Bencher) {
- do_bench_extend(b, 0, 10)
-}
-
-#[bench]
-fn bench_extend_0000_0100(b: &mut Bencher) {
- do_bench_extend(b, 0, 100)
-}
-
-#[bench]
-fn bench_extend_0000_1000(b: &mut Bencher) {
- do_bench_extend(b, 0, 1000)
-}
-
-#[bench]
-fn bench_extend_0010_0010(b: &mut Bencher) {
- do_bench_extend(b, 10, 10)
-}
-
-#[bench]
-fn bench_extend_0100_0100(b: &mut Bencher) {
- do_bench_extend(b, 100, 100)
-}
-
-#[bench]
-fn bench_extend_1000_1000(b: &mut Bencher) {
- do_bench_extend(b, 1000, 1000)
-}
-
-fn do_bench_push_all(b: &mut Bencher, dst_len: usize, src_len: usize) {
- let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
- let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
-
- b.bytes = src_len as u64;
-
- b.iter(|| {
- let mut dst = dst.clone();
- dst.extend_from_slice(&src);
- assert_eq!(dst.len(), dst_len + src_len);
- assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
- });
-}
-
-#[bench]
-fn bench_push_all_0000_0000(b: &mut Bencher) {
- do_bench_push_all(b, 0, 0)
-}
-
-#[bench]
-fn bench_push_all_0000_0010(b: &mut Bencher) {
- do_bench_push_all(b, 0, 10)
-}
-
-#[bench]
-fn bench_push_all_0000_0100(b: &mut Bencher) {
- do_bench_push_all(b, 0, 100)
-}
-
-#[bench]
-fn bench_push_all_0000_1000(b: &mut Bencher) {
- do_bench_push_all(b, 0, 1000)
-}
-
-#[bench]
-fn bench_push_all_0010_0010(b: &mut Bencher) {
- do_bench_push_all(b, 10, 10)
-}
-
-#[bench]
-fn bench_push_all_0100_0100(b: &mut Bencher) {
- do_bench_push_all(b, 100, 100)
-}
-
-#[bench]
-fn bench_push_all_1000_1000(b: &mut Bencher) {
- do_bench_push_all(b, 1000, 1000)
-}
-
-fn do_bench_push_all_move(b: &mut Bencher, dst_len: usize, src_len: usize) {
- let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
- let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
-
- b.bytes = src_len as u64;
-
- b.iter(|| {
- let mut dst = dst.clone();
- dst.extend(src.clone());
- assert_eq!(dst.len(), dst_len + src_len);
- assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
- });
-}
-
-#[bench]
-fn bench_push_all_move_0000_0000(b: &mut Bencher) {
- do_bench_push_all_move(b, 0, 0)
-}
-
-#[bench]
-fn bench_push_all_move_0000_0010(b: &mut Bencher) {
- do_bench_push_all_move(b, 0, 10)
-}
-
-#[bench]
-fn bench_push_all_move_0000_0100(b: &mut Bencher) {
- do_bench_push_all_move(b, 0, 100)
-}
-
-#[bench]
-fn bench_push_all_move_0000_1000(b: &mut Bencher) {
- do_bench_push_all_move(b, 0, 1000)
-}
-
-#[bench]
-fn bench_push_all_move_0010_0010(b: &mut Bencher) {
- do_bench_push_all_move(b, 10, 10)
-}
-
-#[bench]
-fn bench_push_all_move_0100_0100(b: &mut Bencher) {
- do_bench_push_all_move(b, 100, 100)
-}
-
-#[bench]
-fn bench_push_all_move_1000_1000(b: &mut Bencher) {
- do_bench_push_all_move(b, 1000, 1000)
-}
-
-fn do_bench_clone(b: &mut Bencher, src_len: usize) {
- let src: Vec<usize> = FromIterator::from_iter(0..src_len);
-
- b.bytes = src_len as u64;
-
- b.iter(|| {
- let dst = src.clone();
- assert_eq!(dst.len(), src_len);
- assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
- });
-}
-
-#[bench]
-fn bench_clone_0000(b: &mut Bencher) {
- do_bench_clone(b, 0)
-}
-
-#[bench]
-fn bench_clone_0010(b: &mut Bencher) {
- do_bench_clone(b, 10)
-}
-
-#[bench]
-fn bench_clone_0100(b: &mut Bencher) {
- do_bench_clone(b, 100)
-}
-
-#[bench]
-fn bench_clone_1000(b: &mut Bencher) {
- do_bench_clone(b, 1000)
-}
-
-fn do_bench_clone_from(b: &mut Bencher, times: usize, dst_len: usize, src_len: usize) {
- let dst: Vec<_> = FromIterator::from_iter(0..src_len);
- let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
-
- b.bytes = (times * src_len) as u64;
-
- b.iter(|| {
- let mut dst = dst.clone();
-
- for _ in 0..times {
- dst.clone_from(&src);
-
- assert_eq!(dst.len(), src_len);
- assert!(dst.iter().enumerate().all(|(i, x)| dst_len + i == *x));
- }
- });
-}
-
-#[bench]
-fn bench_clone_from_01_0000_0000(b: &mut Bencher) {
- do_bench_clone_from(b, 1, 0, 0)
-}
-
-#[bench]
-fn bench_clone_from_01_0000_0010(b: &mut Bencher) {
- do_bench_clone_from(b, 1, 0, 10)
-}
-
-#[bench]
-fn bench_clone_from_01_0000_0100(b: &mut Bencher) {
- do_bench_clone_from(b, 1, 0, 100)
-}
-
-#[bench]
-fn bench_clone_from_01_0000_1000(b: &mut Bencher) {
- do_bench_clone_from(b, 1, 0, 1000)
-}
-
-#[bench]
-fn bench_clone_from_01_0010_0010(b: &mut Bencher) {
- do_bench_clone_from(b, 1, 10, 10)
-}
-
-#[bench]
-fn bench_clone_from_01_0100_0100(b: &mut Bencher) {
- do_bench_clone_from(b, 1, 100, 100)
-}
-
-#[bench]
-fn bench_clone_from_01_1000_1000(b: &mut Bencher) {
- do_bench_clone_from(b, 1, 1000, 1000)
-}
-
-#[bench]
-fn bench_clone_from_01_0010_0100(b: &mut Bencher) {
- do_bench_clone_from(b, 1, 10, 100)
-}
-
-#[bench]
-fn bench_clone_from_01_0100_1000(b: &mut Bencher) {
- do_bench_clone_from(b, 1, 100, 1000)
-}
-
-#[bench]
-fn bench_clone_from_01_0010_0000(b: &mut Bencher) {
- do_bench_clone_from(b, 1, 10, 0)
-}
-
-#[bench]
-fn bench_clone_from_01_0100_0010(b: &mut Bencher) {
- do_bench_clone_from(b, 1, 100, 10)
-}
-
-#[bench]
-fn bench_clone_from_01_1000_0100(b: &mut Bencher) {
- do_bench_clone_from(b, 1, 1000, 100)
-}
-
-#[bench]
-fn bench_clone_from_10_0000_0000(b: &mut Bencher) {
- do_bench_clone_from(b, 10, 0, 0)
-}
-
-#[bench]
-fn bench_clone_from_10_0000_0010(b: &mut Bencher) {
- do_bench_clone_from(b, 10, 0, 10)
-}
-
-#[bench]
-fn bench_clone_from_10_0000_0100(b: &mut Bencher) {
- do_bench_clone_from(b, 10, 0, 100)
-}
-
-#[bench]
-fn bench_clone_from_10_0000_1000(b: &mut Bencher) {
- do_bench_clone_from(b, 10, 0, 1000)
-}
-
-#[bench]
-fn bench_clone_from_10_0010_0010(b: &mut Bencher) {
- do_bench_clone_from(b, 10, 10, 10)
-}
-
-#[bench]
-fn bench_clone_from_10_0100_0100(b: &mut Bencher) {
- do_bench_clone_from(b, 10, 100, 100)
-}
-
-#[bench]
-fn bench_clone_from_10_1000_1000(b: &mut Bencher) {
- do_bench_clone_from(b, 10, 1000, 1000)
-}
-
-#[bench]
-fn bench_clone_from_10_0010_0100(b: &mut Bencher) {
- do_bench_clone_from(b, 10, 10, 100)
-}
-
-#[bench]
-fn bench_clone_from_10_0100_1000(b: &mut Bencher) {
- do_bench_clone_from(b, 10, 100, 1000)
-}
-
-#[bench]
-fn bench_clone_from_10_0010_0000(b: &mut Bencher) {
- do_bench_clone_from(b, 10, 10, 0)
-}
-
-#[bench]
-fn bench_clone_from_10_0100_0010(b: &mut Bencher) {
- do_bench_clone_from(b, 10, 100, 10)
-}
-
-#[bench]
-fn bench_clone_from_10_1000_0100(b: &mut Bencher) {
- do_bench_clone_from(b, 10, 1000, 100)
-}
use std::fmt::Debug;
use std::collections::vec_deque::Drain;
-use test;
-
use self::Taggy::*;
use self::Taggypar::*;
deq[3];
}
-#[bench]
-fn bench_new(b: &mut test::Bencher) {
- b.iter(|| {
- let ring: VecDeque<i32> = VecDeque::new();
- test::black_box(ring);
- })
-}
-
-#[bench]
-fn bench_grow_1025(b: &mut test::Bencher) {
- b.iter(|| {
- let mut deq = VecDeque::new();
- for i in 0..1025 {
- deq.push_front(i);
- }
- test::black_box(deq);
- })
-}
-
-#[bench]
-fn bench_iter_1000(b: &mut test::Bencher) {
- let ring: VecDeque<_> = (0..1000).collect();
-
- b.iter(|| {
- let mut sum = 0;
- for &i in &ring {
- sum += i;
- }
- test::black_box(sum);
- })
-}
-
-#[bench]
-fn bench_mut_iter_1000(b: &mut test::Bencher) {
- let mut ring: VecDeque<_> = (0..1000).collect();
-
- b.iter(|| {
- let mut sum = 0;
- for i in &mut ring {
- sum += *i;
- }
- test::black_box(sum);
- })
-}
-
#[derive(Clone, PartialEq, Debug)]
enum Taggy {
One(i32),
path = "../libcoretest/lib.rs"
[[bench]]
-name = "corebench"
-path = "../libcore/bench/lib.rs"
+name = "corebenches"
+path = "../libcore/benches/lib.rs"
+++ /dev/null
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use core::any::*;
-use test::{Bencher, black_box};
-
-#[bench]
-fn bench_downcast_ref(b: &mut Bencher) {
- b.iter(|| {
- let mut x = 0;
- let mut y = &mut x as &mut Any;
- black_box(&mut y);
- black_box(y.downcast_ref::<isize>() == Some(&0));
- });
-}
+++ /dev/null
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-mod sip;
+++ /dev/null
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(deprecated)]
-
-use core::hash::*;
-use test::{Bencher, black_box};
-
-fn hash_bytes<H: Hasher>(mut s: H, x: &[u8]) -> u64 {
- Hasher::write(&mut s, x);
- s.finish()
-}
-
-fn hash_with<H: Hasher, T: Hash>(mut st: H, x: &T) -> u64 {
- x.hash(&mut st);
- st.finish()
-}
-
-fn hash<T: Hash>(x: &T) -> u64 {
- hash_with(SipHasher::new(), x)
-}
-
-#[bench]
-fn bench_str_under_8_bytes(b: &mut Bencher) {
- let s = "foo";
- b.iter(|| {
- assert_eq!(hash(&s), 16262950014981195938);
- })
-}
-
-#[bench]
-fn bench_str_of_8_bytes(b: &mut Bencher) {
- let s = "foobar78";
- b.iter(|| {
- assert_eq!(hash(&s), 4898293253460910787);
- })
-}
-
-#[bench]
-fn bench_str_over_8_bytes(b: &mut Bencher) {
- let s = "foobarbaz0";
- b.iter(|| {
- assert_eq!(hash(&s), 10581415515220175264);
- })
-}
-
-#[bench]
-fn bench_long_str(b: &mut Bencher) {
- let s = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor \
-incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud \
-exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute \
-irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla \
-pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui \
-officia deserunt mollit anim id est laborum.";
- b.iter(|| {
- assert_eq!(hash(&s), 17717065544121360093);
- })
-}
-
-#[bench]
-fn bench_u32(b: &mut Bencher) {
- let u = 162629500u32;
- let u = black_box(u);
- b.iter(|| {
- hash(&u)
- });
- b.bytes = 8;
-}
-
-#[bench]
-fn bench_u32_keyed(b: &mut Bencher) {
- let u = 162629500u32;
- let u = black_box(u);
- let k1 = black_box(0x1);
- let k2 = black_box(0x2);
- b.iter(|| {
- hash_with(SipHasher::new_with_keys(k1, k2), &u)
- });
- b.bytes = 8;
-}
-
-#[bench]
-fn bench_u64(b: &mut Bencher) {
- let u = 16262950014981195938u64;
- let u = black_box(u);
- b.iter(|| {
- hash(&u)
- });
- b.bytes = 8;
-}
-
-#[bench]
-fn bench_bytes_4(b: &mut Bencher) {
- let data = black_box([b' '; 4]);
- b.iter(|| {
- hash_bytes(SipHasher::default(), &data)
- });
- b.bytes = 4;
-}
-
-#[bench]
-fn bench_bytes_7(b: &mut Bencher) {
- let data = black_box([b' '; 7]);
- b.iter(|| {
- hash_bytes(SipHasher::default(), &data)
- });
- b.bytes = 7;
-}
-
-#[bench]
-fn bench_bytes_8(b: &mut Bencher) {
- let data = black_box([b' '; 8]);
- b.iter(|| {
- hash_bytes(SipHasher::default(), &data)
- });
- b.bytes = 8;
-}
-
-#[bench]
-fn bench_bytes_a_16(b: &mut Bencher) {
- let data = black_box([b' '; 16]);
- b.iter(|| {
- hash_bytes(SipHasher::default(), &data)
- });
- b.bytes = 16;
-}
-
-#[bench]
-fn bench_bytes_b_32(b: &mut Bencher) {
- let data = black_box([b' '; 32]);
- b.iter(|| {
- hash_bytes(SipHasher::default(), &data)
- });
- b.bytes = 32;
-}
-
-#[bench]
-fn bench_bytes_c_128(b: &mut Bencher) {
- let data = black_box([b' '; 128]);
- b.iter(|| {
- hash_bytes(SipHasher::default(), &data)
- });
- b.bytes = 128;
-}
+++ /dev/null
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use core::iter::*;
-use test::{Bencher, black_box};
-
-#[bench]
-fn bench_rposition(b: &mut Bencher) {
- let it: Vec<usize> = (0..300).collect();
- b.iter(|| {
- it.iter().rposition(|&x| x <= 150);
- });
-}
-
-#[bench]
-fn bench_skip_while(b: &mut Bencher) {
- b.iter(|| {
- let it = 0..100;
- let mut sum = 0;
- it.skip_while(|&x| { sum += x; sum < 4000 }).all(|_| true);
- });
-}
-
-#[bench]
-fn bench_multiple_take(b: &mut Bencher) {
- let mut it = (0..42).cycle();
- b.iter(|| {
- let n = it.next().unwrap();
- for _ in 0..n {
- it.clone().take(it.next().unwrap()).all(|_| true);
- }
- });
-}
-
-fn scatter(x: i32) -> i32 { (x * 31) % 127 }
-
-#[bench]
-fn bench_max_by_key(b: &mut Bencher) {
- b.iter(|| {
- let it = 0..100;
- it.max_by_key(|&x| scatter(x))
- })
-}
-
-// http://www.reddit.com/r/rust/comments/31syce/using_iterators_to_find_the_index_of_the_min_or/
-#[bench]
-fn bench_max_by_key2(b: &mut Bencher) {
- fn max_index_iter(array: &[i32]) -> usize {
- array.iter().enumerate().max_by_key(|&(_, item)| item).unwrap().0
- }
-
- let mut data = vec![0; 1638];
- data[514] = 9999;
-
- b.iter(|| max_index_iter(&data));
-}
-
-#[bench]
-fn bench_max(b: &mut Bencher) {
- b.iter(|| {
- let it = 0..100;
- it.map(scatter).max()
- })
-}
-
-pub fn copy_zip(xs: &[u8], ys: &mut [u8]) {
- for (a, b) in ys.iter_mut().zip(xs) {
- *a = *b;
- }
-}
-
-pub fn add_zip(xs: &[f32], ys: &mut [f32]) {
- for (a, b) in ys.iter_mut().zip(xs) {
- *a += *b;
- }
-}
-
-#[bench]
-fn bench_zip_copy(b: &mut Bencher) {
- let source = vec![0u8; 16 * 1024];
- let mut dst = black_box(vec![0u8; 16 * 1024]);
- b.iter(|| {
- copy_zip(&source, &mut dst)
- })
-}
-
-#[bench]
-fn bench_zip_add(b: &mut Bencher) {
- let source = vec![1.; 16 * 1024];
- let mut dst = vec![0.; 16 * 1024];
- b.iter(|| {
- add_zip(&source, &mut dst)
- });
-}
+++ /dev/null
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![deny(warnings)]
-
-#![feature(flt2dec)]
-#![feature(slice_patterns)]
-#![feature(test)]
-
-extern crate core;
-extern crate test;
-
-mod any;
-mod hash;
-mod iter;
-mod mem;
-mod num;
-mod ops;
+++ /dev/null
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use test::Bencher;
-
-// FIXME #13642 (these benchmarks should be in another place)
-// Completely miscellaneous language-construct benchmarks.
-// Static/dynamic method dispatch
-
-struct Struct {
- field: isize
-}
-
-trait Trait {
- fn method(&self) -> isize;
-}
-
-impl Trait for Struct {
- fn method(&self) -> isize {
- self.field
- }
-}
-
-#[bench]
-fn trait_vtable_method_call(b: &mut Bencher) {
- let s = Struct { field: 10 };
- let t = &s as &Trait;
- b.iter(|| {
- t.method()
- });
-}
-
-#[bench]
-fn trait_static_method_call(b: &mut Bencher) {
- let s = Struct { field: 10 };
- b.iter(|| {
- s.method()
- });
-}
-
-// Overhead of various match forms
-
-#[bench]
-fn match_option_some(b: &mut Bencher) {
- let x = Some(10);
- b.iter(|| {
- match x {
- Some(y) => y,
- None => 11
- }
- });
-}
-
-#[bench]
-fn match_vec_pattern(b: &mut Bencher) {
- let x = [1,2,3,4,5,6];
- b.iter(|| {
- match x {
- [1,2,3,..] => 10,
- _ => 11,
- }
- });
-}
+++ /dev/null
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::f64;
-use test::Bencher;
-
-#[bench]
-fn bench_0(b: &mut Bencher) {
- b.iter(|| "0.0".parse::<f64>());
-}
-
-#[bench]
-fn bench_42(b: &mut Bencher) {
- b.iter(|| "42".parse::<f64>());
-}
-
-#[bench]
-fn bench_huge_int(b: &mut Bencher) {
- // 2^128 - 1
- b.iter(|| "170141183460469231731687303715884105727".parse::<f64>());
-}
-
-#[bench]
-fn bench_short_decimal(b: &mut Bencher) {
- b.iter(|| "1234.5678".parse::<f64>());
-}
-
-#[bench]
-fn bench_pi_long(b: &mut Bencher) {
- b.iter(|| "3.14159265358979323846264338327950288".parse::<f64>());
-}
-
-#[bench]
-fn bench_pi_short(b: &mut Bencher) {
- b.iter(|| "3.141592653589793".parse::<f64>())
-}
-
-#[bench]
-fn bench_1e150(b: &mut Bencher) {
- b.iter(|| "1e150".parse::<f64>());
-}
-
-#[bench]
-fn bench_long_decimal_and_exp(b: &mut Bencher) {
- b.iter(|| "727501488517303786137132964064381141071e-123".parse::<f64>());
-}
-
-#[bench]
-fn bench_min_subnormal(b: &mut Bencher) {
- b.iter(|| "5e-324".parse::<f64>());
-}
-
-#[bench]
-fn bench_min_normal(b: &mut Bencher) {
- b.iter(|| "2.2250738585072014e-308".parse::<f64>());
-}
-
-#[bench]
-fn bench_max(b: &mut Bencher) {
- b.iter(|| "1.7976931348623157e308".parse::<f64>());
-}
+++ /dev/null
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-mod strategy {
- mod dragon;
- mod grisu;
-}
-
-use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded};
-use core::num::flt2dec::MAX_SIG_DIGITS;
-
-pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
- match decode(v).1 {
- FullDecoded::Finite(decoded) => decoded,
- full_decoded => panic!("expected finite, got {:?} instead", full_decoded)
- }
-}
+++ /dev/null
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::{i16, f64};
-use super::super::*;
-use core::num::flt2dec::strategy::dragon::*;
-use test::Bencher;
-
-#[bench]
-fn bench_small_shortest(b: &mut Bencher) {
- let decoded = decode_finite(3.141592f64);
- let mut buf = [0; MAX_SIG_DIGITS];
- b.iter(|| format_shortest(&decoded, &mut buf));
-}
-
-#[bench]
-fn bench_big_shortest(b: &mut Bencher) {
- let decoded = decode_finite(f64::MAX);
- let mut buf = [0; MAX_SIG_DIGITS];
- b.iter(|| format_shortest(&decoded, &mut buf));
-}
-
-#[bench]
-fn bench_small_exact_3(b: &mut Bencher) {
- let decoded = decode_finite(3.141592f64);
- let mut buf = [0; 3];
- b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
-}
-
-#[bench]
-fn bench_big_exact_3(b: &mut Bencher) {
- let decoded = decode_finite(f64::MAX);
- let mut buf = [0; 3];
- b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
-}
-
-#[bench]
-fn bench_small_exact_12(b: &mut Bencher) {
- let decoded = decode_finite(3.141592f64);
- let mut buf = [0; 12];
- b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
-}
-
-#[bench]
-fn bench_big_exact_12(b: &mut Bencher) {
- let decoded = decode_finite(f64::MAX);
- let mut buf = [0; 12];
- b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
-}
-
-#[bench]
-fn bench_small_exact_inf(b: &mut Bencher) {
- let decoded = decode_finite(3.141592f64);
- let mut buf = [0; 1024];
- b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
-}
-
-#[bench]
-fn bench_big_exact_inf(b: &mut Bencher) {
- let decoded = decode_finite(f64::MAX);
- let mut buf = [0; 1024];
- b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
-}
+++ /dev/null
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::{i16, f64};
-use super::super::*;
-use core::num::flt2dec::strategy::grisu::*;
-use test::Bencher;
-
-pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
- match decode(v).1 {
- FullDecoded::Finite(decoded) => decoded,
- full_decoded => panic!("expected finite, got {:?} instead", full_decoded)
- }
-}
-
-#[bench]
-fn bench_small_shortest(b: &mut Bencher) {
- let decoded = decode_finite(3.141592f64);
- let mut buf = [0; MAX_SIG_DIGITS];
- b.iter(|| format_shortest(&decoded, &mut buf));
-}
-
-#[bench]
-fn bench_big_shortest(b: &mut Bencher) {
- let decoded = decode_finite(f64::MAX);
- let mut buf = [0; MAX_SIG_DIGITS];
- b.iter(|| format_shortest(&decoded, &mut buf));
-}
-
-#[bench]
-fn bench_small_exact_3(b: &mut Bencher) {
- let decoded = decode_finite(3.141592f64);
- let mut buf = [0; 3];
- b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
-}
-
-#[bench]
-fn bench_big_exact_3(b: &mut Bencher) {
- let decoded = decode_finite(f64::MAX);
- let mut buf = [0; 3];
- b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
-}
-
-#[bench]
-fn bench_small_exact_12(b: &mut Bencher) {
- let decoded = decode_finite(3.141592f64);
- let mut buf = [0; 12];
- b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
-}
-
-#[bench]
-fn bench_big_exact_12(b: &mut Bencher) {
- let decoded = decode_finite(f64::MAX);
- let mut buf = [0; 12];
- b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
-}
-
-#[bench]
-fn bench_small_exact_inf(b: &mut Bencher) {
- let decoded = decode_finite(3.141592f64);
- let mut buf = [0; 1024];
- b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
-}
-
-#[bench]
-fn bench_big_exact_inf(b: &mut Bencher) {
- let decoded = decode_finite(f64::MAX);
- let mut buf = [0; 1024];
- b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
-}
+++ /dev/null
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-mod flt2dec;
-mod dec2flt;
+++ /dev/null
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use core::ops::*;
-use test::Bencher;
-
-// Overhead of dtors
-
-struct HasDtor {
- _x: isize
-}
-
-impl Drop for HasDtor {
- fn drop(&mut self) {
- }
-}
-
-#[bench]
-fn alloc_obj_with_dtor(b: &mut Bencher) {
- b.iter(|| {
- HasDtor { _x : 10 };
- })
-}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use core::any::*;
+use test::{Bencher, black_box};
+
+#[bench]
+fn bench_downcast_ref(b: &mut Bencher) {
+ b.iter(|| {
+ let mut x = 0;
+ let mut y = &mut x as &mut Any;
+ black_box(&mut y);
+ black_box(y.downcast_ref::<isize>() == Some(&0));
+ });
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod sip;
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(deprecated)]
+
+use core::hash::*;
+use test::{Bencher, black_box};
+
+fn hash_bytes<H: Hasher>(mut s: H, x: &[u8]) -> u64 {
+ Hasher::write(&mut s, x);
+ s.finish()
+}
+
+fn hash_with<H: Hasher, T: Hash>(mut st: H, x: &T) -> u64 {
+ x.hash(&mut st);
+ st.finish()
+}
+
+fn hash<T: Hash>(x: &T) -> u64 {
+ hash_with(SipHasher::new(), x)
+}
+
+#[bench]
+fn bench_str_under_8_bytes(b: &mut Bencher) {
+ let s = "foo";
+ b.iter(|| {
+ assert_eq!(hash(&s), 16262950014981195938);
+ })
+}
+
+#[bench]
+fn bench_str_of_8_bytes(b: &mut Bencher) {
+ let s = "foobar78";
+ b.iter(|| {
+ assert_eq!(hash(&s), 4898293253460910787);
+ })
+}
+
+#[bench]
+fn bench_str_over_8_bytes(b: &mut Bencher) {
+ let s = "foobarbaz0";
+ b.iter(|| {
+ assert_eq!(hash(&s), 10581415515220175264);
+ })
+}
+
+#[bench]
+fn bench_long_str(b: &mut Bencher) {
+ let s = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor \
+incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud \
+exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute \
+irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla \
+pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui \
+officia deserunt mollit anim id est laborum.";
+ b.iter(|| {
+ assert_eq!(hash(&s), 17717065544121360093);
+ })
+}
+
+#[bench]
+fn bench_u32(b: &mut Bencher) {
+ let u = 162629500u32;
+ let u = black_box(u);
+ b.iter(|| {
+ hash(&u)
+ });
+ b.bytes = 8;
+}
+
+#[bench]
+fn bench_u32_keyed(b: &mut Bencher) {
+ let u = 162629500u32;
+ let u = black_box(u);
+ let k1 = black_box(0x1);
+ let k2 = black_box(0x2);
+ b.iter(|| {
+ hash_with(SipHasher::new_with_keys(k1, k2), &u)
+ });
+ b.bytes = 8;
+}
+
+#[bench]
+fn bench_u64(b: &mut Bencher) {
+ let u = 16262950014981195938u64;
+ let u = black_box(u);
+ b.iter(|| {
+ hash(&u)
+ });
+ b.bytes = 8;
+}
+
+#[bench]
+fn bench_bytes_4(b: &mut Bencher) {
+ let data = black_box([b' '; 4]);
+ b.iter(|| {
+ hash_bytes(SipHasher::default(), &data)
+ });
+ b.bytes = 4;
+}
+
+#[bench]
+fn bench_bytes_7(b: &mut Bencher) {
+ let data = black_box([b' '; 7]);
+ b.iter(|| {
+ hash_bytes(SipHasher::default(), &data)
+ });
+ b.bytes = 7;
+}
+
+#[bench]
+fn bench_bytes_8(b: &mut Bencher) {
+ let data = black_box([b' '; 8]);
+ b.iter(|| {
+ hash_bytes(SipHasher::default(), &data)
+ });
+ b.bytes = 8;
+}
+
+#[bench]
+fn bench_bytes_a_16(b: &mut Bencher) {
+ let data = black_box([b' '; 16]);
+ b.iter(|| {
+ hash_bytes(SipHasher::default(), &data)
+ });
+ b.bytes = 16;
+}
+
+#[bench]
+fn bench_bytes_b_32(b: &mut Bencher) {
+ let data = black_box([b' '; 32]);
+ b.iter(|| {
+ hash_bytes(SipHasher::default(), &data)
+ });
+ b.bytes = 32;
+}
+
+#[bench]
+fn bench_bytes_c_128(b: &mut Bencher) {
+ let data = black_box([b' '; 128]);
+ b.iter(|| {
+ hash_bytes(SipHasher::default(), &data)
+ });
+ b.bytes = 128;
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use core::iter::*;
+use test::{Bencher, black_box};
+
+#[bench]
+fn bench_rposition(b: &mut Bencher) {
+ let it: Vec<usize> = (0..300).collect();
+ b.iter(|| {
+ it.iter().rposition(|&x| x <= 150);
+ });
+}
+
+#[bench]
+fn bench_skip_while(b: &mut Bencher) {
+ b.iter(|| {
+ let it = 0..100;
+ let mut sum = 0;
+ it.skip_while(|&x| { sum += x; sum < 4000 }).all(|_| true);
+ });
+}
+
+#[bench]
+fn bench_multiple_take(b: &mut Bencher) {
+ let mut it = (0..42).cycle();
+ b.iter(|| {
+ let n = it.next().unwrap();
+ for _ in 0..n {
+ it.clone().take(it.next().unwrap()).all(|_| true);
+ }
+ });
+}
+
+fn scatter(x: i32) -> i32 { (x * 31) % 127 }
+
+#[bench]
+fn bench_max_by_key(b: &mut Bencher) {
+ b.iter(|| {
+ let it = 0..100;
+ it.max_by_key(|&x| scatter(x))
+ })
+}
+
+// http://www.reddit.com/r/rust/comments/31syce/using_iterators_to_find_the_index_of_the_min_or/
+#[bench]
+fn bench_max_by_key2(b: &mut Bencher) {
+ fn max_index_iter(array: &[i32]) -> usize {
+ array.iter().enumerate().max_by_key(|&(_, item)| item).unwrap().0
+ }
+
+ let mut data = vec![0; 1638];
+ data[514] = 9999;
+
+ b.iter(|| max_index_iter(&data));
+}
+
+#[bench]
+fn bench_max(b: &mut Bencher) {
+ b.iter(|| {
+ let it = 0..100;
+ it.map(scatter).max()
+ })
+}
+
+pub fn copy_zip(xs: &[u8], ys: &mut [u8]) {
+ for (a, b) in ys.iter_mut().zip(xs) {
+ *a = *b;
+ }
+}
+
+pub fn add_zip(xs: &[f32], ys: &mut [f32]) {
+ for (a, b) in ys.iter_mut().zip(xs) {
+ *a += *b;
+ }
+}
+
+#[bench]
+fn bench_zip_copy(b: &mut Bencher) {
+ let source = vec![0u8; 16 * 1024];
+ let mut dst = black_box(vec![0u8; 16 * 1024]);
+ b.iter(|| {
+ copy_zip(&source, &mut dst)
+ })
+}
+
+#[bench]
+fn bench_zip_add(b: &mut Bencher) {
+ let source = vec![1.; 16 * 1024];
+ let mut dst = vec![0.; 16 * 1024];
+ b.iter(|| {
+ add_zip(&source, &mut dst)
+ });
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![deny(warnings)]
+
+#![feature(flt2dec)]
+#![feature(slice_patterns)]
+#![feature(test)]
+
+extern crate core;
+extern crate test;
+
+mod any;
+mod hash;
+mod iter;
+mod mem;
+mod num;
+mod ops;
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use test::Bencher;
+
+// FIXME #13642 (these benchmarks should be in another place)
+// Completely miscellaneous language-construct benchmarks.
+// Static/dynamic method dispatch
+
+struct Struct {
+ field: isize
+}
+
+trait Trait {
+ fn method(&self) -> isize;
+}
+
+impl Trait for Struct {
+ fn method(&self) -> isize {
+ self.field
+ }
+}
+
+#[bench]
+fn trait_vtable_method_call(b: &mut Bencher) {
+ let s = Struct { field: 10 };
+ let t = &s as &Trait;
+ b.iter(|| {
+ t.method()
+ });
+}
+
+#[bench]
+fn trait_static_method_call(b: &mut Bencher) {
+ let s = Struct { field: 10 };
+ b.iter(|| {
+ s.method()
+ });
+}
+
+// Overhead of various match forms
+
+#[bench]
+fn match_option_some(b: &mut Bencher) {
+ let x = Some(10);
+ b.iter(|| {
+ match x {
+ Some(y) => y,
+ None => 11
+ }
+ });
+}
+
+#[bench]
+fn match_vec_pattern(b: &mut Bencher) {
+ let x = [1,2,3,4,5,6];
+ b.iter(|| {
+ match x {
+ [1,2,3,..] => 10,
+ _ => 11,
+ }
+ });
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::f64;
+use test::Bencher;
+
+#[bench]
+fn bench_0(b: &mut Bencher) {
+ b.iter(|| "0.0".parse::<f64>());
+}
+
+#[bench]
+fn bench_42(b: &mut Bencher) {
+ b.iter(|| "42".parse::<f64>());
+}
+
+#[bench]
+fn bench_huge_int(b: &mut Bencher) {
+ // 2^128 - 1
+ b.iter(|| "170141183460469231731687303715884105727".parse::<f64>());
+}
+
+#[bench]
+fn bench_short_decimal(b: &mut Bencher) {
+ b.iter(|| "1234.5678".parse::<f64>());
+}
+
+#[bench]
+fn bench_pi_long(b: &mut Bencher) {
+ b.iter(|| "3.14159265358979323846264338327950288".parse::<f64>());
+}
+
+#[bench]
+fn bench_pi_short(b: &mut Bencher) {
+ b.iter(|| "3.141592653589793".parse::<f64>())
+}
+
+#[bench]
+fn bench_1e150(b: &mut Bencher) {
+ b.iter(|| "1e150".parse::<f64>());
+}
+
+#[bench]
+fn bench_long_decimal_and_exp(b: &mut Bencher) {
+ b.iter(|| "727501488517303786137132964064381141071e-123".parse::<f64>());
+}
+
+#[bench]
+fn bench_min_subnormal(b: &mut Bencher) {
+ b.iter(|| "5e-324".parse::<f64>());
+}
+
+#[bench]
+fn bench_min_normal(b: &mut Bencher) {
+ b.iter(|| "2.2250738585072014e-308".parse::<f64>());
+}
+
+#[bench]
+fn bench_max(b: &mut Bencher) {
+ b.iter(|| "1.7976931348623157e308".parse::<f64>());
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod strategy {
+ mod dragon;
+ mod grisu;
+}
+
+use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded};
+use core::num::flt2dec::MAX_SIG_DIGITS;
+
+pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
+ match decode(v).1 {
+ FullDecoded::Finite(decoded) => decoded,
+ full_decoded => panic!("expected finite, got {:?} instead", full_decoded)
+ }
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::{i16, f64};
+use super::super::*;
+use core::num::flt2dec::strategy::dragon::*;
+use test::Bencher;
+
+#[bench]
+fn bench_small_shortest(b: &mut Bencher) {
+ let decoded = decode_finite(3.141592f64);
+ let mut buf = [0; MAX_SIG_DIGITS];
+ b.iter(|| format_shortest(&decoded, &mut buf));
+}
+
+#[bench]
+fn bench_big_shortest(b: &mut Bencher) {
+ let decoded = decode_finite(f64::MAX);
+ let mut buf = [0; MAX_SIG_DIGITS];
+ b.iter(|| format_shortest(&decoded, &mut buf));
+}
+
+#[bench]
+fn bench_small_exact_3(b: &mut Bencher) {
+ let decoded = decode_finite(3.141592f64);
+ let mut buf = [0; 3];
+ b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+}
+
+#[bench]
+fn bench_big_exact_3(b: &mut Bencher) {
+ let decoded = decode_finite(f64::MAX);
+ let mut buf = [0; 3];
+ b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+}
+
+#[bench]
+fn bench_small_exact_12(b: &mut Bencher) {
+ let decoded = decode_finite(3.141592f64);
+ let mut buf = [0; 12];
+ b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+}
+
+#[bench]
+fn bench_big_exact_12(b: &mut Bencher) {
+ let decoded = decode_finite(f64::MAX);
+ let mut buf = [0; 12];
+ b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+}
+
+#[bench]
+fn bench_small_exact_inf(b: &mut Bencher) {
+ let decoded = decode_finite(3.141592f64);
+ let mut buf = [0; 1024];
+ b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+}
+
+#[bench]
+fn bench_big_exact_inf(b: &mut Bencher) {
+ let decoded = decode_finite(f64::MAX);
+ let mut buf = [0; 1024];
+ b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::{i16, f64};
+use super::super::*;
+use core::num::flt2dec::strategy::grisu::*;
+use test::Bencher;
+
+pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
+ match decode(v).1 {
+ FullDecoded::Finite(decoded) => decoded,
+ full_decoded => panic!("expected finite, got {:?} instead", full_decoded)
+ }
+}
+
+#[bench]
+fn bench_small_shortest(b: &mut Bencher) {
+ let decoded = decode_finite(3.141592f64);
+ let mut buf = [0; MAX_SIG_DIGITS];
+ b.iter(|| format_shortest(&decoded, &mut buf));
+}
+
+#[bench]
+fn bench_big_shortest(b: &mut Bencher) {
+ let decoded = decode_finite(f64::MAX);
+ let mut buf = [0; MAX_SIG_DIGITS];
+ b.iter(|| format_shortest(&decoded, &mut buf));
+}
+
+#[bench]
+fn bench_small_exact_3(b: &mut Bencher) {
+ let decoded = decode_finite(3.141592f64);
+ let mut buf = [0; 3];
+ b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+}
+
+#[bench]
+fn bench_big_exact_3(b: &mut Bencher) {
+ let decoded = decode_finite(f64::MAX);
+ let mut buf = [0; 3];
+ b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+}
+
+#[bench]
+fn bench_small_exact_12(b: &mut Bencher) {
+ let decoded = decode_finite(3.141592f64);
+ let mut buf = [0; 12];
+ b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+}
+
+#[bench]
+fn bench_big_exact_12(b: &mut Bencher) {
+ let decoded = decode_finite(f64::MAX);
+ let mut buf = [0; 12];
+ b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+}
+
+#[bench]
+fn bench_small_exact_inf(b: &mut Bencher) {
+ let decoded = decode_finite(3.141592f64);
+ let mut buf = [0; 1024];
+ b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+}
+
+#[bench]
+fn bench_big_exact_inf(b: &mut Bencher) {
+ let decoded = decode_finite(f64::MAX);
+ let mut buf = [0; 1024];
+ b.iter(|| format_exact(&decoded, &mut buf, i16::MIN));
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod flt2dec;
+mod dec2flt;
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use core::ops::*;
+use test::Bencher;
+
+// Overhead of dtors
+
+struct HasDtor {
+ _x: isize
+}
+
+impl Drop for HasDtor {
+ fn drop(&mut self) {
+ }
+}
+
+#[bench]
+fn alloc_obj_with_dtor(b: &mut Bencher) {
+ b.iter(|| {
+ HasDtor { _x : 10 };
+ })
+}
// Recreate the edges in the graph that are still clean.
let mut clean_work_products = FxHashSet();
let mut dirty_work_products = FxHashSet(); // incomplete; just used to suppress debug output
+ let mut extra_edges = vec![];
for (source, targets) in &edge_map {
for target in targets {
- // If the target is dirty, skip the edge. If this is an edge
- // that targets a work-product, we can print the blame
- // information now.
- if let Some(blame) = dirty_raw_nodes.get(target) {
- if let DepNode::WorkProduct(ref wp) = *target {
- if tcx.sess.opts.debugging_opts.incremental_info {
- if dirty_work_products.insert(wp.clone()) {
- // It'd be nice to pretty-print these paths better than just
- // using the `Debug` impls, but wev.
- println!("incremental: module {:?} is dirty because {:?} \
- changed or was removed",
- wp,
- blame.map_def(|&index| {
- Some(directory.def_path_string(tcx, index))
- }).unwrap());
- }
- }
- }
- continue;
- }
-
- // If the source is dirty, the target will be dirty.
- assert!(!dirty_raw_nodes.contains_key(source));
-
- // Retrace the source -> target edges to def-ids and then
- // create an edge in the graph. Retracing may yield none if
- // some of the data happens to have been removed; this ought
- // to be impossible unless it is dirty, so we can unwrap.
- let source_node = retraced.map(source).unwrap();
- let target_node = retraced.map(target).unwrap();
- let _task = tcx.dep_graph.in_task(target_node);
- tcx.dep_graph.read(source_node);
- if let DepNode::WorkProduct(ref wp) = *target {
- clean_work_products.insert(wp.clone());
- }
+ process_edges(tcx, source, target, &edge_map, &directory, &retraced, &dirty_raw_nodes,
+ &mut clean_work_products, &mut dirty_work_products, &mut extra_edges);
}
}
+ // Subtle. Sometimes we have intermediate nodes that we can't recreate in the new graph.
+ // This is pretty unusual but it arises in a scenario like this:
+ //
+ // Hir(X) -> Foo(Y) -> Bar
+ //
+ // Note that the `Hir(Y)` is not an input to `Foo(Y)` -- this
+ // almost never happens, but can happen in some obscure
+ // scenarios. In that case, if `Y` is removed, then we can't
+ // recreate `Foo(Y)` (the def-id `Y` no longer exists); what we do
+ // then is to push the edge `Hir(X) -> Bar` onto `extra_edges`
+ // (along with any other targets of `Foo(Y)`). We will then add
+ // the edge from `Hir(X)` to `Bar` (or, if `Bar` itself cannot be
+ // recreated, to the targets of `Bar`).
+ while let Some((source, target)) = extra_edges.pop() {
+ process_edges(tcx, source, target, &edge_map, &directory, &retraced, &dirty_raw_nodes,
+ &mut clean_work_products, &mut dirty_work_products, &mut extra_edges);
+ }
+
// Add in work-products that are still clean, and delete those that are
// dirty.
reconcile_work_products(tcx, work_products, &clean_work_products);
serialized_hashes.index_map.len());
}
+fn process_edges<'a, 'tcx, 'edges>(
+ tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ source: &'edges DepNode<DefPathIndex>,
+ target: &'edges DepNode<DefPathIndex>,
+ edges: &'edges FxHashMap<DepNode<DefPathIndex>, Vec<DepNode<DefPathIndex>>>,
+ directory: &DefIdDirectory,
+ retraced: &RetracedDefIdDirectory,
+ dirty_raw_nodes: &DirtyNodes,
+ clean_work_products: &mut FxHashSet<Arc<WorkProductId>>,
+ dirty_work_products: &mut FxHashSet<Arc<WorkProductId>>,
+ extra_edges: &mut Vec<(&'edges DepNode<DefPathIndex>, &'edges DepNode<DefPathIndex>)>)
+{
+ // If the target is dirty, skip the edge. If this is an edge
+ // that targets a work-product, we can print the blame
+ // information now.
+ if let Some(blame) = dirty_raw_nodes.get(target) {
+ if let DepNode::WorkProduct(ref wp) = *target {
+ if tcx.sess.opts.debugging_opts.incremental_info {
+ if dirty_work_products.insert(wp.clone()) {
+ // It'd be nice to pretty-print these paths better than just
+ // using the `Debug` impls, but wev.
+ println!("incremental: module {:?} is dirty because {:?} \
+ changed or was removed",
+ wp,
+ blame.map_def(|&index| {
+ Some(directory.def_path_string(tcx, index))
+ }).unwrap());
+ }
+ }
+ }
+ return;
+ }
+
+ // If the source is dirty, the target will be dirty.
+ assert!(!dirty_raw_nodes.contains_key(source));
+
+ // Retrace the source -> target edges to def-ids and then create
+ // an edge in the graph. Retracing may yield none if some of the
+ // data happens to have been removed.
+ if let Some(source_node) = retraced.map(source) {
+ if let Some(target_node) = retraced.map(target) {
+ let _task = tcx.dep_graph.in_task(target_node);
+ tcx.dep_graph.read(source_node);
+ if let DepNode::WorkProduct(ref wp) = *target {
+ clean_work_products.insert(wp.clone());
+ }
+ } else {
+ // As discussed in `decode_dep_graph` above, sometimes the
+ // target cannot be recreated again, in which case we add
+ // edges to go from `source` to the targets of `target`.
+ extra_edges.extend(
+ edges[target].iter().map(|t| (source, t)));
+ }
+ } else {
+ // It's also possible that the source can't be created! But we
+ // can ignore such cases, because (a) if `source` is a HIR
+ // node, it would be considered dirty; and (b) in other cases,
+ // there must be some input to this node that is clean, and so
+ // we'll re-create the edges over in the case where target is
+ // undefined.
+ }
+}
+
enum FfiResult {
FfiSafe,
+ FfiPhantom,
FfiUnsafe(&'static str),
FfiBadStruct(DefId, &'static str),
FfiBadUnion(DefId, &'static str),
impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
/// Check if the given type is "ffi-safe" (has a stable, well-defined
/// representation which can be exported to C code).
- fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> FfiResult {
+ fn check_type_for_ffi(&self,
+ cache: &mut FxHashSet<Ty<'tcx>>,
+ ty: Ty<'tcx>) -> FfiResult {
use self::FfiResult::*;
+
let cx = self.cx.tcx;
// Protect against infinite recursion, for example
match ty.sty {
ty::TyAdt(def, substs) => {
+ if def.is_phantom_data() {
+ return FfiPhantom;
+ }
match def.adt_kind() {
AdtKind::Struct => {
if !cx.lookup_repr_hints(def.did).contains(&attr::ReprExtern) {
consider adding a #[repr(C)] attribute to the type");
}
- // We can't completely trust repr(C) markings; make sure the
- // fields are actually safe.
if def.struct_variant().fields.is_empty() {
return FfiUnsafe("found zero-size struct in foreign module, consider \
adding a member to this struct");
}
+ // We can't completely trust repr(C) markings; make sure the
+ // fields are actually safe.
+ let mut all_phantom = true;
for field in &def.struct_variant().fields {
let field_ty = cx.normalize_associated_type(&field.ty(cx, substs));
let r = self.check_type_for_ffi(cache, field_ty);
match r {
- FfiSafe => {}
+ FfiSafe => {
+ all_phantom = false;
+ }
+ FfiPhantom => {}
FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => {
return r;
}
}
}
}
- FfiSafe
+
+ if all_phantom { FfiPhantom } else { FfiSafe }
}
AdtKind::Union => {
if !cx.lookup_repr_hints(def.did).contains(&attr::ReprExtern) {
consider adding a #[repr(C)] attribute to the type");
}
+ if def.struct_variant().fields.is_empty() {
+ return FfiUnsafe("found zero-size union in foreign module, consider \
+ adding a member to this union");
+ }
+
+ let mut all_phantom = true;
for field in &def.struct_variant().fields {
let field_ty = cx.normalize_associated_type(&field.ty(cx, substs));
let r = self.check_type_for_ffi(cache, field_ty);
match r {
- FfiSafe => {}
+ FfiSafe => {
+ all_phantom = false;
+ }
+ FfiPhantom => {}
FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => {
return r;
}
}
}
}
- FfiSafe
+
+ if all_phantom { FfiPhantom } else { FfiSafe }
}
AdtKind::Enum => {
if def.variants.is_empty() {
FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => {
return r;
}
+ FfiPhantom => {
+ return FfiBadEnum(def.did,
+ "Found phantom data in enum variant");
+ }
FfiUnsafe(s) => {
return FfiBadEnum(def.did, s);
}
match self.check_type_for_ffi(&mut FxHashSet(), ty) {
FfiResult::FfiSafe => {}
+ FfiResult::FfiPhantom => {
+ self.cx.span_lint(IMPROPER_CTYPES,
+ sp,
+ &format!("found zero-sized type composed only \
+ of phantom-data in a foreign-function."));
+ }
FfiResult::FfiUnsafe(s) => {
self.cx.span_lint(IMPROPER_CTYPES, sp, s);
}
pub fn LLVMRustDIBuilderCreateBasicType(Builder: DIBuilderRef,
Name: *const c_char,
SizeInBits: u64,
- AlignInBits: u64,
+ AlignInBits: u32,
Encoding: c_uint)
-> DIBasicType;
pub fn LLVMRustDIBuilderCreatePointerType(Builder: DIBuilderRef,
PointeeTy: DIType,
SizeInBits: u64,
- AlignInBits: u64,
+ AlignInBits: u32,
Name: *const c_char)
-> DIDerivedType;
File: DIFile,
LineNumber: c_uint,
SizeInBits: u64,
- AlignInBits: u64,
+ AlignInBits: u32,
Flags: DIFlags,
DerivedFrom: DIType,
Elements: DIArray,
File: DIFile,
LineNo: c_uint,
SizeInBits: u64,
- AlignInBits: u64,
+ AlignInBits: u32,
OffsetInBits: u64,
Flags: DIFlags,
Ty: DIType)
isLocalToUnit: bool,
Val: ValueRef,
Decl: DIDescriptor,
- AlignInBits: u64)
+ AlignInBits: u32)
-> DIGlobalVariable;
pub fn LLVMRustDIBuilderCreateVariable(Builder: DIBuilderRef,
AlwaysPreserve: bool,
Flags: DIFlags,
ArgNo: c_uint,
- AlignInBits: u64)
+ AlignInBits: u32)
-> DIVariable;
pub fn LLVMRustDIBuilderCreateArrayType(Builder: DIBuilderRef,
Size: u64,
- AlignInBits: u64,
+ AlignInBits: u32,
Ty: DIType,
Subscripts: DIArray)
-> DIType;
pub fn LLVMRustDIBuilderCreateVectorType(Builder: DIBuilderRef,
Size: u64,
- AlignInBits: u64,
+ AlignInBits: u32,
Ty: DIType,
Subscripts: DIArray)
-> DIType;
File: DIFile,
LineNumber: c_uint,
SizeInBits: u64,
- AlignInBits: u64,
+ AlignInBits: u32,
Elements: DIArray,
ClassType: DIType)
-> DIType;
File: DIFile,
LineNumber: c_uint,
SizeInBits: u64,
- AlignInBits: u64,
+ AlignInBits: u32,
Flags: DIFlags,
Elements: DIArray,
RunTimeLang: c_uint,
use syntax_pos::MultiSpan;
use context::{is_pie_binary, get_reloc_model};
+use std::cmp;
use std::ffi::CString;
use std::fs;
use std::path::{Path, PathBuf};
}
// Process the work items, optionally using worker threads.
- // NOTE: This code is not really adapted to incremental compilation where
- // the compiler decides the number of codegen units (and will
- // potentially create hundreds of them).
- let num_workers = work_items.len() - 1;
+ // NOTE: We are hardcoding a limit of worker threads for now. With
+ // incremental compilation we can run into situations where we would
+ // open hundreds of threads otherwise -- which can make things slower
+ // if things don't fit into memory anymore, or can cause the compiler
+ // to crash because of too many open file handles. See #39280 for
+ // some discussion on how to improve this in the future.
+ let num_workers = cmp::min(work_items.len() - 1, 32);
if num_workers <= 1 {
run_work_singlethreaded(sess, &trans.exported_symbols, work_items);
} else {
is_local_to_unit,
global,
ptr::null_mut(),
- global_align as u64,
+ global_align,
);
}
}
cx.sess().opts.optimize != config::OptLevel::No,
DIFlags::FlagZero,
argument_index,
- align as u64,
+ align,
)
};
source_loc::set_debug_location(bcx,
use syntax_pos::{self, Span};
use syntax::ast;
+use std::ops;
+
pub fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool
{
// The is_local_to_unit flag indicates whether a function is local to the
cx.sess().codemap().lookup_char_pos(span.lo)
}
-pub fn size_and_align_of(cx: &CrateContext, llvm_type: Type) -> (u64, u64) {
- (machine::llsize_of_alloc(cx, llvm_type), machine::llalign_of_min(cx, llvm_type) as u64)
+pub fn size_and_align_of(cx: &CrateContext, llvm_type: Type) -> (u64, u32) {
+ (machine::llsize_of_alloc(cx, llvm_type), machine::llalign_of_min(cx, llvm_type))
}
-pub fn bytes_to_bits(bytes: u64) -> u64 {
- bytes * 8
+pub fn bytes_to_bits<T>(bytes: T) -> T
+ where T: ops::Mul<Output=T> + From<u8> {
+ bytes * 8u8.into()
}
#[inline]
use std::slice;
use std::str;
use syntax::feature_gate::UnstableFeatures;
+use syntax::codemap::Span;
use html::render::derive_id;
use html::toc::TocBuilder;
}
}
-pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, start_line: usize) {
+pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Span) {
extern fn block(_ob: *mut hoedown_buffer,
text: *const hoedown_buffer,
lang: *const hoedown_buffer,
});
let text = lines.collect::<Vec<&str>>().join("\n");
let line = tests.get_line() + line;
+ let filename = tests.get_filename();
tests.add_test(text.to_owned(),
block_info.should_panic, block_info.no_run,
block_info.ignore, block_info.test_harness,
block_info.compile_fail, block_info.error_codes,
- line);
+ line, filename);
}
}
}
}
- tests.set_line(start_line);
+ tests.set_position(position);
unsafe {
let ob = hoedown_buffer_new(DEF_OUNIT);
let renderer = hoedown_html_renderer_new(0, 0);
use testing;
use rustc::session::search_paths::SearchPaths;
use rustc::session::config::Externs;
+use syntax::codemap::DUMMY_SP;
use externalfiles::{ExternalHtml, LoadStringError, load_string};
let mut opts = TestOptions::default();
opts.no_crate_inject = true;
let mut collector = Collector::new(input.to_string(), cfgs, libs, externs,
- true, opts, maybe_sysroot, "input".to_string(),
- None);
- find_testable_code(&input_str, &mut collector, 0);
+ true, opts, maybe_sysroot, None);
+ find_testable_code(&input_str, &mut collector, DUMMY_SP);
test_args.insert(0, "rustdoctest".to_string());
testing::test_main(&test_args, collector.tests);
0
use syntax::ast;
use syntax::codemap::CodeMap;
use syntax::feature_gate::UnstableFeatures;
-use syntax_pos::{BytePos, DUMMY_SP, Pos};
+use syntax_pos::{BytePos, DUMMY_SP, Pos, Span};
use errors;
use errors::emitter::ColorConfig;
link::find_crate_name(None, &hir_forest.krate().attrs, &input)
});
let opts = scrape_test_config(hir_forest.krate());
- let filename = input_path.to_str().unwrap_or("").to_owned();
let mut collector = Collector::new(crate_name,
cfgs,
libs,
false,
opts,
maybe_sysroot,
- filename,
Some(codemap));
{
cratename: String,
opts: TestOptions,
maybe_sysroot: Option<PathBuf>,
- filename: String,
- start_line: usize,
+ position: Span,
codemap: Option<Rc<CodeMap>>,
}
impl Collector {
pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
use_headers: bool, opts: TestOptions, maybe_sysroot: Option<PathBuf>,
- filename: String, codemap: Option<Rc<CodeMap>>) -> Collector {
+ codemap: Option<Rc<CodeMap>>) -> Collector {
Collector {
tests: Vec::new(),
names: Vec::new(),
cratename: cratename,
opts: opts,
maybe_sysroot: maybe_sysroot,
- filename: filename,
- start_line: 0,
+ position: DUMMY_SP,
codemap: codemap,
}
}
pub fn add_test(&mut self, test: String,
should_panic: bool, no_run: bool, should_ignore: bool,
as_test_harness: bool, compile_fail: bool, error_codes: Vec<String>,
- line: usize) {
- let name = format!("{} - line {}", self.filename, line);
+ line: usize, filename: String) {
+ let name = format!("{} - line {}", filename, line);
self.cnt += 1;
let cfgs = self.cfgs.clone();
let libs = self.libs.clone();
}
pub fn get_line(&self) -> usize {
- if let Some(ref codemap) = self.codemap{
- let line = codemap.lookup_char_pos(BytePos(self.start_line as u32)).line;
+ if let Some(ref codemap) = self.codemap {
+ let line = self.position.lo.to_usize();
+ let line = codemap.lookup_char_pos(BytePos(line as u32)).line;
if line > 0 { line - 1 } else { line }
} else {
- self.start_line
+ 0
}
}
- pub fn set_line(&mut self, start_line: usize) {
- self.start_line = start_line;
+ pub fn set_position(&mut self, position: Span) {
+ self.position = position;
+ }
+
+ pub fn get_filename(&self) -> String {
+ if let Some(ref codemap) = self.codemap {
+ codemap.span_to_filename(self.position)
+ } else {
+ "<input>".to_owned()
+ }
}
pub fn register_header(&mut self, name: &str, level: u32) {
if let Some(doc) = attrs.doc_value() {
self.collector.cnt = 0;
markdown::find_testable_code(doc, self.collector,
- attrs.span.unwrap_or(DUMMY_SP).lo.to_usize());
+ attrs.span.unwrap_or(DUMMY_SP));
}
nested(self);
/// guaranteed to repeatedly return a successful exit status so long as the
/// child has already exited.
///
- /// If the child has exited, then `Ok(status)` is returned. If the exit
- /// status is not available at this time then an error is returned with the
- /// error kind `WouldBlock`. If an error occurs, then that error is returned.
+ /// If the child has exited, then `Ok(Some(status))` is returned. If the
+ /// exit status is not available at this time then `Ok(None)` is returned.
+ /// If an error occurs, then that error is returned.
///
/// Note that unlike `wait`, this function will not attempt to drop stdin.
///
/// ```no_run
/// #![feature(process_try_wait)]
///
- /// use std::io;
/// use std::process::Command;
///
/// let mut child = Command::new("ls").spawn().unwrap();
///
/// match child.try_wait() {
- /// Ok(status) => println!("exited with: {}", status),
- /// Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+ /// Ok(Some(status)) => println!("exited with: {}", status),
+ /// Ok(None) => {
/// println!("status not ready yet, let's really wait");
/// let res = child.wait();
/// println!("result: {:?}", res);
/// }
/// ```
#[unstable(feature = "process_try_wait", issue = "38903")]
- pub fn try_wait(&mut self) -> io::Result<ExitStatus> {
- self.handle.try_wait().map(ExitStatus)
+ pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
+ Ok(self.handle.try_wait()?.map(ExitStatus))
}
/// Simultaneously waits for the child to exit and collect all remaining
Ok(ExitStatus(status as i32))
}
- pub fn try_wait(&mut self) -> io::Result<ExitStatus> {
+ pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
if let Some(status) = self.status {
- return Ok(status)
+ return Ok(Some(status))
}
let mut status = 0;
let pid = cvt(syscall::waitpid(self.pid, &mut status, syscall::WNOHANG))?;
if pid == 0 {
- Err(io::Error::from_raw_os_error(syscall::EWOULDBLOCK))
+ Ok(None)
} else {
self.status = Some(ExitStatus(status as i32));
- Ok(ExitStatus(status as i32))
+ Ok(Some(ExitStatus(status as i32)))
}
}
}
Ok(ExitStatus::new(proc_info.rec.return_code))
}
- pub fn try_wait(&mut self) -> io::Result<ExitStatus> {
+ pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
use default::Default;
use sys::process::magenta::*;
match status {
0 => { }, // Success
x if x == ERR_TIMED_OUT => {
- return Err(io::Error::from(io::ErrorKind::WouldBlock));
+ return Ok(None);
},
_ => { panic!("Failed to wait on process handle: {}", status); },
}
return Err(io::Error::new(io::ErrorKind::InvalidData,
"Failed to get exit status of process"));
}
- Ok(ExitStatus::new(proc_info.rec.return_code))
+ Ok(Some(ExitStatus::new(proc_info.rec.return_code)))
}
}
Ok(ExitStatus::new(status))
}
- pub fn try_wait(&mut self) -> io::Result<ExitStatus> {
+ pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
if let Some(status) = self.status {
- return Ok(status)
+ return Ok(Some(status))
}
let mut status = 0 as c_int;
let pid = cvt(unsafe {
libc::waitpid(self.pid, &mut status, libc::WNOHANG)
})?;
if pid == 0 {
- Err(io::Error::from_raw_os_error(libc::EWOULDBLOCK))
+ Ok(None)
} else {
self.status = Some(ExitStatus::new(status));
- Ok(ExitStatus::new(status))
+ Ok(Some(ExitStatus::new(status)))
}
}
}
}
}
- pub fn try_wait(&mut self) -> io::Result<ExitStatus> {
+ pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
unsafe {
match c::WaitForSingleObject(self.handle.raw(), 0) {
c::WAIT_OBJECT_0 => {}
c::WAIT_TIMEOUT => {
- return Err(io::Error::from_raw_os_error(c::WSAEWOULDBLOCK))
+ return Ok(None);
}
_ => return Err(io::Error::last_os_error()),
}
let mut status = 0;
cvt(c::GetExitCodeProcess(self.handle.raw(), &mut status))?;
- Ok(ExitStatus(status))
+ Ok(Some(ExitStatus(status)))
}
}
//! by two zero-length breaks. The algorithm will try its best to fit it on a
//! line (which it can't) and so naturally place the content on its own line to
//! avoid combining it with other lines and making matters even worse.
+//!
+//! # Explanation
+//!
+//! In case you do not have the paper, here is an explanation of what's going
+//! on.
+//!
+//! There is a stream of input tokens flowing through this printer.
+//!
+//! The printer buffers up to 3N tokens inside itself, where N is linewidth.
+//! Yes, linewidth is chars and tokens are multi-char, but in the worst
+//! case every token worth buffering is 1 char long, so it's ok.
+//!
+//! Tokens are String, Break, and Begin/End to delimit blocks.
+//!
+//! Begin tokens can carry an offset, saying "how far to indent when you break
+//! inside here", as well as a flag indicating "consistent" or "inconsistent"
+//! breaking. Consistent breaking means that after the first break, no attempt
+//! will be made to flow subsequent breaks together onto lines. Inconsistent
+//! is the opposite. Inconsistent breaking example would be, say:
+//!
+//! ```
+//! foo(hello, there, good, friends)
+//! ```
+//!
+//! breaking inconsistently to become
+//!
+//! ```
+//! foo(hello, there
+//! good, friends);
+//! ```
+//!
+//! whereas a consistent breaking would yield:
+//!
+//! ```
+//! foo(hello,
+//! there
+//! good,
+//! friends);
+//! ```
+//!
+//! That is, in the consistent-break blocks we value vertical alignment
+//! more than the ability to cram stuff onto a line. But in all cases if it
+//! can make a block a one-liner, it'll do so.
+//!
+//! Carrying on with high-level logic:
+//!
+//! The buffered tokens go through a ring-buffer, 'tokens'. The 'left' and
+//! 'right' indices denote the active portion of the ring buffer as well as
+//! describing hypothetical points-in-the-infinite-stream at most 3N tokens
+//! apart (i.e. "not wrapped to ring-buffer boundaries"). The paper will switch
+//! between using 'left' and 'right' terms to denote the wrapped-to-ring-buffer
+//! and point-in-infinite-stream senses freely.
+//!
+//! There is a parallel ring buffer, 'size', that holds the calculated size of
+//! each token. Why calculated? Because for Begin/End pairs, the "size"
+//! includes everything between the pair. That is, the "size" of Begin is
+//! actually the sum of the sizes of everything between Begin and the paired
+//! End that follows. Since that is arbitrarily far in the future, 'size' is
+//! being rewritten regularly while the printer runs; in fact most of the
+//! machinery is here to work out 'size' entries on the fly (and give up when
+//! they're so obviously over-long that "infinity" is a good enough
+//! approximation for purposes of line breaking).
+//!
+//! The "input side" of the printer is managed as an abstract process called
+//! SCAN, which uses 'scan_stack', to manage calculating 'size'. SCAN is, in
+//! other words, the process of calculating 'size' entries.
+//!
+//! The "output side" of the printer is managed by an abstract process called
+//! PRINT, which uses 'print_stack', 'margin' and 'space' to figure out what to
+//! do with each token/size pair it consumes as it goes. It's trying to consume
+//! the entire buffered window, but can't output anything until the size is >=
+//! 0 (sizes are set to negative while they're pending calculation).
+//!
+//! So SCAN takes input and buffers tokens and pending calculations, while
+//! PRINT gobbles up completed calculations and tokens from the buffer. The
+//! theory is that the two can never get more than 3N tokens apart, because
+//! once there's "obviously" too much data to fit on a line, in a size
+//! calculation, SCAN will write "infinity" to the size and let PRINT consume
+//! it.
+//!
+//! In this implementation (following the paper, again) the SCAN process is
+//! the method called `Printer::pretty_print`, and the 'PRINT' process is the method
+//! called `Printer::print`.
use std::collections::VecDeque;
use std::fmt;
use std::io;
+/// How to break. Described in more detail in the module docs.
#[derive(Clone, Copy, PartialEq)]
pub enum Breaks {
Consistent,
}
}
-
-/// In case you do not have the paper, here is an explanation of what's going
-/// on.
-///
-/// There is a stream of input tokens flowing through this printer.
-///
-/// The printer buffers up to 3N tokens inside itself, where N is linewidth.
-/// Yes, linewidth is chars and tokens are multi-char, but in the worst
-/// case every token worth buffering is 1 char long, so it's ok.
-///
-/// Tokens are String, Break, and Begin/End to delimit blocks.
-///
-/// Begin tokens can carry an offset, saying "how far to indent when you break
-/// inside here", as well as a flag indicating "consistent" or "inconsistent"
-/// breaking. Consistent breaking means that after the first break, no attempt
-/// will be made to flow subsequent breaks together onto lines. Inconsistent
-/// is the opposite. Inconsistent breaking example would be, say:
-///
-/// foo(hello, there, good, friends)
-///
-/// breaking inconsistently to become
-///
-/// foo(hello, there
-/// good, friends);
-///
-/// whereas a consistent breaking would yield:
-///
-/// foo(hello,
-/// there
-/// good,
-/// friends);
-///
-/// That is, in the consistent-break blocks we value vertical alignment
-/// more than the ability to cram stuff onto a line. But in all cases if it
-/// can make a block a one-liner, it'll do so.
-///
-/// Carrying on with high-level logic:
-///
-/// The buffered tokens go through a ring-buffer, 'tokens'. The 'left' and
-/// 'right' indices denote the active portion of the ring buffer as well as
-/// describing hypothetical points-in-the-infinite-stream at most 3N tokens
-/// apart (i.e. "not wrapped to ring-buffer boundaries"). The paper will switch
-/// between using 'left' and 'right' terms to denote the wrapped-to-ring-buffer
-/// and point-in-infinite-stream senses freely.
-///
-/// There is a parallel ring buffer, 'size', that holds the calculated size of
-/// each token. Why calculated? Because for Begin/End pairs, the "size"
-/// includes everything between the pair. That is, the "size" of Begin is
-/// actually the sum of the sizes of everything between Begin and the paired
-/// End that follows. Since that is arbitrarily far in the future, 'size' is
-/// being rewritten regularly while the printer runs; in fact most of the
-/// machinery is here to work out 'size' entries on the fly (and give up when
-/// they're so obviously over-long that "infinity" is a good enough
-/// approximation for purposes of line breaking).
-///
-/// The "input side" of the printer is managed as an abstract process called
-/// SCAN, which uses 'scan_stack', to manage calculating 'size'. SCAN is, in
-/// other words, the process of calculating 'size' entries.
-///
-/// The "output side" of the printer is managed by an abstract process called
-/// PRINT, which uses 'print_stack', 'margin' and 'space' to figure out what to
-/// do with each token/size pair it consumes as it goes. It's trying to consume
-/// the entire buffered window, but can't output anything until the size is >=
-/// 0 (sizes are set to negative while they're pending calculation).
-///
-/// So SCAN takes input and buffers tokens and pending calculations, while
-/// PRINT gobbles up completed calculations and tokens from the buffer. The
-/// theory is that the two can never get more than 3N tokens apart, because
-/// once there's "obviously" too much data to fit on a line, in a size
-/// calculation, SCAN will write "infinity" to the size and let PRINT consume
-/// it.
-///
-/// In this implementation (following the paper, again) the SCAN process is
-/// the method called 'pretty_print', and the 'PRINT' process is the method
-/// called 'print'.
pub struct Printer<'a> {
pub out: Box<io::Write+'a>,
buf_len: usize,
pub fn last_token(&mut self) -> Token {
self.buf[self.right].token.clone()
}
- // be very careful with this!
+ /// be very careful with this!
pub fn replace_last_token(&mut self, t: Token) {
self.buf[self.right].token = t;
}
}
// Convenience functions to talk to the printer.
-//
-// "raw box"
+
+/// "raw box"
pub fn rbox(p: &mut Printer, indent: usize, b: Breaks) -> io::Result<()> {
p.pretty_print(Token::Begin(BeginToken {
offset: indent as isize,
}))
}
+/// Inconsistent breaking box
pub fn ibox(p: &mut Printer, indent: usize) -> io::Result<()> {
rbox(p, indent, Breaks::Inconsistent)
}
+/// Consistent breaking box
pub fn cbox(p: &mut Printer, indent: usize) -> io::Result<()> {
rbox(p, indent, Breaks::Consistent)
}
extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateBasicType(LLVMRustDIBuilderRef Builder, const char *Name,
- uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t SizeInBits, uint32_t AlignInBits,
unsigned Encoding) {
return wrap(Builder->createBasicType(Name, SizeInBits,
#if LLVM_VERSION_LE(3, 9)
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreatePointerType(
LLVMRustDIBuilderRef Builder, LLVMRustMetadataRef PointeeTy,
- uint64_t SizeInBits, uint64_t AlignInBits, const char *Name) {
+ uint64_t SizeInBits, uint32_t AlignInBits, const char *Name) {
return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
SizeInBits, AlignInBits, Name));
}
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStructType(
LLVMRustDIBuilderRef Builder, LLVMRustMetadataRef Scope, const char *Name,
LLVMRustMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
- uint64_t AlignInBits, LLVMRustDIFlags Flags,
+ uint32_t AlignInBits, LLVMRustDIFlags Flags,
LLVMRustMetadataRef DerivedFrom, LLVMRustMetadataRef Elements,
unsigned RunTimeLang, LLVMRustMetadataRef VTableHolder,
const char *UniqueId) {
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateMemberType(
LLVMRustDIBuilderRef Builder, LLVMRustMetadataRef Scope, const char *Name,
LLVMRustMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
- uint64_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
+ uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
LLVMRustMetadataRef Ty) {
return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope), Name,
unwrapDI<DIFile>(File), LineNo,
LLVMRustDIBuilderRef Builder, LLVMRustMetadataRef Context, const char *Name,
const char *LinkageName, LLVMRustMetadataRef File, unsigned LineNo,
LLVMRustMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
- LLVMRustMetadataRef Decl = nullptr, uint64_t AlignInBits = 0) {
+ LLVMRustMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
Constant *InitVal = cast<Constant>(unwrap(V));
#if LLVM_VERSION_GE(4, 0)
LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMRustMetadataRef Scope,
const char *Name, LLVMRustMetadataRef File, unsigned LineNo,
LLVMRustMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
- unsigned ArgNo, uint64_t AlignInBits) {
+ unsigned ArgNo, uint32_t AlignInBits) {
#if LLVM_VERSION_GE(3, 8)
if (Tag == 0x100) { // DW_TAG_auto_variable
return wrap(Builder->createAutoVariable(
extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
- uint64_t AlignInBits, LLVMRustMetadataRef Ty,
+ uint32_t AlignInBits, LLVMRustMetadataRef Ty,
LLVMRustMetadataRef Subscripts) {
return wrap(
Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateVectorType(LLVMRustDIBuilderRef Builder, uint64_t Size,
- uint64_t AlignInBits, LLVMRustMetadataRef Ty,
+ uint32_t AlignInBits, LLVMRustMetadataRef Ty,
LLVMRustMetadataRef Subscripts) {
return wrap(
Builder->createVectorType(Size, AlignInBits, unwrapDI<DIType>(Ty),
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerationType(
LLVMRustDIBuilderRef Builder, LLVMRustMetadataRef Scope, const char *Name,
LLVMRustMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
- uint64_t AlignInBits, LLVMRustMetadataRef Elements,
+ uint32_t AlignInBits, LLVMRustMetadataRef Elements,
LLVMRustMetadataRef ClassTy) {
return wrap(Builder->createEnumerationType(
unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateUnionType(
LLVMRustDIBuilderRef Builder, LLVMRustMetadataRef Scope, const char *Name,
LLVMRustMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
- uint64_t AlignInBits, LLVMRustDIFlags Flags, LLVMRustMetadataRef Elements,
+ uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMRustMetadataRef Elements,
unsigned RunTimeLang, const char *UniqueId) {
return wrap(Builder->createUnionType(
unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
pub type CVoidRet = ();
pub struct Foo;
+#[repr(C)]
+pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData<i32>);
+
extern {
pub fn ptr_type1(size: *const Foo); //~ ERROR: found struct without
pub fn ptr_type2(size: *const Foo); //~ ERROR: found struct without
pub fn tuple_type(p: (i32, i32)); //~ ERROR found Rust tuple type
pub fn tuple_type2(p: I32Pair); //~ ERROR found Rust tuple type
pub fn zero_size(p: ZeroSize); //~ ERROR found zero-size struct
+ pub fn zero_size_phantom(p: ZeroSizeWithPhantomData); //~ ERROR found zero-sized type
+ pub fn zero_size_phantom_toplevel()
+ -> ::std::marker::PhantomData<bool>; //~ ERROR: found zero-sized type
pub fn fn_type(p: RustFn); //~ ERROR found function pointer with Rust
pub fn fn_type2(p: fn()); //~ ERROR found function pointer with Rust
pub fn fn_contained(p: RustBadRet); //~ ERROR: found struct without
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Regression test for a weird corner case in our dep-graph reduction
+// code. When we solve `CoerceUnsized<Foo>`, we find no impls, so we
+// don't end up with an edge to any HIR nodes, but it still gets
+// preserved in the dep graph.
+
+// revisions:rpass1 rpass2
+// compile-flags: -Z query-dep-graph
+
+use std::sync::Arc;
+
+#[cfg(rpass1)]
+struct Foo { x: usize }
+
+#[cfg(rpass1)]
+fn main() {
+ let x: Arc<Foo> = Arc::new(Foo { x: 22 });
+ let y: Arc<Foo> = x;
+}
+
+#[cfg(rpass2)]
+struct FooX { x: usize }
+
+#[cfg(rpass2)]
+fn main() {
+ let x: Arc<FooX> = Arc::new(FooX { x: 22 });
+ let y: Arc<FooX> = x;
+}
+
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![forbid(improper_ctypes)]
+#![allow(dead_code)]
+
+#[repr(C)]
+pub struct Foo {
+ size: u8,
+ __value: ::std::marker::PhantomData<i32>,
+}
+
+#[repr(C)]
+pub struct ZeroSizeWithPhantomData<T>(::std::marker::PhantomData<T>);
+
+#[repr(C)]
+pub struct Bar {
+ size: u8,
+ baz: ZeroSizeWithPhantomData<i32>,
+}
+
+extern "C" {
+ pub fn bar(_: *mut Foo, _: *mut Bar);
+}
+
+fn main() {
+}
#![feature(process_try_wait)]
use std::env;
-use std::io;
use std::process::Command;
use std::thread;
use std::time::Duration;
.arg("sleep")
.spawn()
.unwrap();
- let err = me.try_wait().unwrap_err();
- assert_eq!(err.kind(), io::ErrorKind::WouldBlock);
- let err = me.try_wait().unwrap_err();
- assert_eq!(err.kind(), io::ErrorKind::WouldBlock);
+ let maybe_status = me.try_wait().unwrap();
+ assert!(maybe_status.is_none());
+ let maybe_status = me.try_wait().unwrap();
+ assert!(maybe_status.is_none());
me.kill().unwrap();
me.wait().unwrap();
- let status = me.try_wait().unwrap();
+ let status = me.try_wait().unwrap().unwrap();
assert!(!status.success());
- let status = me.try_wait().unwrap();
+ let status = me.try_wait().unwrap().unwrap();
assert!(!status.success());
let mut me = Command::new(env::current_exe().unwrap())
.unwrap();
loop {
match me.try_wait() {
- Ok(res) => {
+ Ok(Some(res)) => {
assert!(res.success());
break
}
- Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+ Ok(None) => {
thread::sleep(Duration::from_millis(1));
}
Err(e) => panic!("error in try_wait: {}", e),
}
}
- let status = me.try_wait().unwrap();
+ let status = me.try_wait().unwrap().unwrap();
assert!(status.success());
}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: --test
+// check-test-line-numbers-match
+
+/// This looks like another awesome test!
+///
+/// ```
+/// println!("foo?");
+/// ```
+pub fn foooo() {}
// compile-flags: --test
// check-test-line-numbers-match
+pub mod bar;
+
/// This is a Foo;
///
/// ```
extern crate toml;
extern crate rustc_serialize;
-use std::collections::HashMap;
+use std::collections::{BTreeMap, HashMap};
use std::env;
use std::fs::File;
use std::io::{self, Read, Write};
"x86_64-pc-windows-gnu",
];
-#[derive(RustcEncodable)]
struct Manifest {
manifest_version: String,
date: String,
self.cargo_version = self.version("cargo", "x86_64-unknown-linux-gnu");
self.digest_and_sign();
- let manifest = self.build_manifest();
- let manifest = toml::encode(&manifest).to_string();
+ let Manifest { manifest_version, date, pkg } = self.build_manifest();
+
+ // Unfortunately we can't use derive(RustcEncodable) here because the
+ // version field is called `manifest-version`, not `manifest_version`.
+ // In lieu of that just create the table directly here with a `BTreeMap`
+ // and wrap it up in a `Value::Table`.
+ let mut manifest = BTreeMap::new();
+ manifest.insert("manifest-version".to_string(),
+ toml::encode(&manifest_version));
+ manifest.insert("date".to_string(), toml::encode(&date));
+ manifest.insert("pkg".to_string(), toml::encode(&pkg));
+ let manifest = toml::Value::Table(manifest).to_string();
let filename = format!("channel-rust-{}.toml", self.channel);
self.write_manifest(&manifest, &filename);
use std::path::{Path, PathBuf};
use std::process::{Command, Output, ExitStatus};
use std::str;
+use std::collections::HashMap;
use extract_gdb_version;
}
}
- fn check_rustdoc_test_option(&self, res: ProcRes) {
- let mut file = fs::File::open(&self.testpaths.file)
+ fn get_lines<P: AsRef<Path>>(&self, path: &P,
+ mut other_files: Option<&mut Vec<String>>) -> Vec<usize> {
+ let mut file = fs::File::open(path)
.expect("markdown_test_output_check_entry File::open failed");
let mut content = String::new();
file.read_to_string(&mut content)
.expect("markdown_test_output_check_entry read_to_string failed");
let mut ignore = false;
- let mut v: Vec<usize> =
- content.lines()
- .enumerate()
- .filter_map(|(line_nb, line)| {
+ content.lines()
+ .enumerate()
+ .filter_map(|(line_nb, line)| {
+ if (line.trim_left().starts_with("pub mod ") ||
+ line.trim_left().starts_with("mod ")) &&
+ line.ends_with(";") {
+ if let Some(ref mut other_files) = other_files {
+ other_files.push(line.rsplit("mod ")
+ .next()
+ .unwrap()
+ .replace(";", ""));
+ }
+ None
+ } else {
let sline = line.split("///").last().unwrap_or("");
let line = sline.trim_left();
if line.starts_with("```") {
} else {
None
}
- })
- .collect();
+ }
+ })
+ .collect()
+ }
+
+ fn check_rustdoc_test_option(&self, res: ProcRes) {
+ let mut other_files = Vec::new();
+ let mut files: HashMap<String, Vec<usize>> = HashMap::new();
+ files.insert(self.testpaths.file.to_str().unwrap().to_owned(),
+ self.get_lines(&self.testpaths.file, Some(&mut other_files)));
+ for other_file in other_files {
+ let mut path = self.testpaths.file.clone();
+ path.set_file_name(&format!("{}.rs", other_file));
+ files.insert(path.to_str().unwrap().to_owned(), self.get_lines(&path, None));
+ }
let mut tested = 0;
for _ in res.stdout.split("\n")
.inspect(|s| {
let tmp: Vec<&str> = s.split(" - line ").collect();
if tmp.len() == 2 {
- tested += 1;
- let line = tmp[1].split(" ...")
- .next()
- .unwrap_or("0")
- .parse()
- .unwrap_or(0);
- if let Ok(pos) = v.binary_search(&line) {
- v.remove(pos);
- } else {
- self.fatal_proc_rec(
- &format!("Not found doc test: \"{}\" in {:?}", s, v),
- &res);
+ let path = tmp[0].rsplit("test ").next().unwrap();
+ if let Some(ref mut v) = files.get_mut(path) {
+ tested += 1;
+ let line = tmp[1].split(" ...")
+ .next()
+ .unwrap_or("0")
+ .parse()
+ .unwrap_or(0);
+ if let Ok(pos) = v.binary_search(&line) {
+ v.remove(pos);
+ } else {
+ self.fatal_proc_rec(
+ &format!("Not found doc test: \"{}\" in \"{}\":{:?}",
+ s, path, v),
+ &res);
+ }
}
}
}) {}
if tested == 0 {
- self.fatal_proc_rec("No test has been found", &res);
- } else if v.len() != 0 {
- self.fatal_proc_rec(&format!("Not found test at line{} {:?}",
- if v.len() > 1 { "s" } else { "" }, v),
- &res);
+ self.fatal_proc_rec(&format!("No test has been found... {:?}", files), &res);
+ } else {
+ for (entry, v) in &files {
+ if v.len() != 0 {
+ self.fatal_proc_rec(&format!("Not found test at line{} \"{}\":{:?}",
+ if v.len() > 1 { "s" } else { "" }, entry, v),
+ &res);
+ }
+ }
}
}