Auto merge of #39645 - frewsxcv:rollup, r=frewsxcv
Rollup of 11 pull requests - Successful merges: #39462, #39512, #39529, #39557, #39561, #39582, #39583, #39597, #39622, #39624, #39630 - Failed merges:
This commit is contained in:
commit
4379e2fa08
@ -1,4 +1,4 @@
|
||||
Version 1.15.1 (2017-02-07)
|
||||
Version 1.15.1 (2017-02-08)
|
||||
===========================
|
||||
|
||||
* [Fix IntoIter::as_mut_slice's signature][39466]
|
||||
|
@ -24,6 +24,7 @@ use Build;
|
||||
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() {
|
||||
|
@ -16,7 +16,6 @@ std_unicode = { path = "../libstd_unicode" }
|
||||
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"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// 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.
|
||||
//
|
||||
@ -8,13 +8,17 @@
|
||||
// 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 ::test::Bencher) {
|
||||
use std::__rand::{thread_rng, Rng};
|
||||
use test::black_box;
|
||||
|
||||
pub fn $name(b: &mut Bencher) {
|
||||
let n: usize = $n;
|
||||
let mut map = $map::new();
|
||||
// setup
|
||||
@ -39,9 +43,7 @@ macro_rules! map_insert_rand_bench {
|
||||
macro_rules! map_insert_seq_bench {
|
||||
($name: ident, $n: expr, $map: ident) => (
|
||||
#[bench]
|
||||
pub fn $name(b: &mut ::test::Bencher) {
|
||||
use test::black_box;
|
||||
|
||||
pub fn $name(b: &mut Bencher) {
|
||||
let mut map = $map::new();
|
||||
let n: usize = $n;
|
||||
// setup
|
||||
@ -64,12 +66,7 @@ macro_rules! map_insert_seq_bench {
|
||||
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;
|
||||
|
||||
pub fn $name(b: &mut Bencher) {
|
||||
let mut map = $map::new();
|
||||
let n: usize = $n;
|
||||
|
||||
@ -97,9 +94,7 @@ macro_rules! map_find_rand_bench {
|
||||
macro_rules! map_find_seq_bench {
|
||||
($name: ident, $n: expr, $map: ident) => (
|
||||
#[bench]
|
||||
pub fn $name(b: &mut ::test::Bencher) {
|
||||
use test::black_box;
|
||||
|
||||
pub fn $name(b: &mut Bencher) {
|
||||
let mut map = $map::new();
|
||||
let n: usize = $n;
|
||||
|
||||
@ -118,3 +113,45 @@ macro_rules! map_find_seq_bench {
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
11
src/libcollections/benches/btree/mod.rs
Normal file
11
src/libcollections/benches/btree/mod.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// 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;
|
24
src/libcollections/benches/lib.rs
Normal file
24
src/libcollections/benches/lib.rs
Normal file
@ -0,0 +1,24 @@
|
||||
// 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;
|
87
src/libcollections/benches/linked_list.rs
Normal file
87
src/libcollections/benches/linked_list.rs
Normal file
@ -0,0 +1,87 @@
|
||||
// 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);
|
||||
})
|
||||
}
|
280
src/libcollections/benches/slice.rs
Normal file
280
src/libcollections/benches/slice.rs
Normal file
@ -0,0 +1,280 @@
|
||||
// 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;
|
||||
}
|
298
src/libcollections/benches/str.rs
Normal file
298
src/libcollections/benches/str.rs
Normal file
@ -0,0 +1,298 @@
|
||||
// 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());
|
134
src/libcollections/benches/string.rs
Normal file
134
src/libcollections/benches/string.rs
Normal file
@ -0,0 +1,134 @@
|
||||
// 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())
|
||||
}
|
492
src/libcollections/benches/vec.rs
Normal file
492
src/libcollections/benches/vec.rs
Normal file
@ -0,0 +1,492 @@
|
||||
// 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)
|
||||
}
|
57
src/libcollections/benches/vec_deque.rs
Normal file
57
src/libcollections/benches/vec_deque.rs
Normal file
@ -0,0 +1,57 @@
|
||||
// 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);
|
||||
})
|
||||
}
|
@ -606,52 +606,3 @@ fn test_split_off_large_random_sorted() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -35,10 +35,6 @@ extern crate std_unicode;
|
||||
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;
|
||||
|
@ -10,8 +10,6 @@
|
||||
|
||||
use std::collections::LinkedList;
|
||||
|
||||
use test;
|
||||
|
||||
#[test]
|
||||
fn test_basic() {
|
||||
let mut m = LinkedList::<Box<_>>::new();
|
||||
@ -356,81 +354,6 @@ fn test_extend() {
|
||||
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();
|
||||
|
@ -1170,276 +1170,3 @@ fn test_copy_from_slice_dst_shorter() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -1564,294 +1564,3 @@ fn different_str_pattern_forwarding_lifetimes() {
|
||||
|
||||
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());
|
||||
}
|
||||
|
@ -9,9 +9,6 @@
|
||||
// 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>;
|
||||
@ -436,125 +433,3 @@ fn test_into_boxed_str() {
|
||||
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())
|
||||
}
|
||||
|
@ -10,13 +10,10 @@
|
||||
|
||||
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,
|
||||
}
|
||||
@ -633,483 +630,3 @@ fn test_placement_panic() {
|
||||
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)
|
||||
}
|
||||
|
@ -12,8 +12,6 @@ use std::collections::VecDeque;
|
||||
use std::fmt::Debug;
|
||||
use std::collections::vec_deque::Drain;
|
||||
|
||||
use test;
|
||||
|
||||
use self::Taggy::*;
|
||||
use self::Taggypar::*;
|
||||
|
||||
@ -124,51 +122,6 @@ fn test_index_out_of_bounds() {
|
||||
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),
|
||||
|
@ -14,5 +14,5 @@ name = "coretest"
|
||||
path = "../libcoretest/lib.rs"
|
||||
|
||||
[[bench]]
|
||||
name = "corebench"
|
||||
path = "../libcore/bench/lib.rs"
|
||||
name = "corebenches"
|
||||
path = "../libcore/benches/lib.rs"
|
||||
|
@ -176,46 +176,32 @@ pub fn decode_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
// 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);
|
||||
@ -393,3 +379,66 @@ fn load_prev_metadata_hashes(tcx: TyCtxt,
|
||||
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.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,6 +339,7 @@ struct ImproperCTypesVisitor<'a, 'tcx: 'a> {
|
||||
|
||||
enum FfiResult {
|
||||
FfiSafe,
|
||||
FfiPhantom,
|
||||
FfiUnsafe(&'static str),
|
||||
FfiBadStruct(DefId, &'static str),
|
||||
FfiBadUnion(DefId, &'static str),
|
||||
@ -383,8 +384,11 @@ fn is_repr_nullable_ptr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
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
|
||||
@ -397,6 +401,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
|
||||
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) {
|
||||
@ -405,18 +412,22 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
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;
|
||||
}
|
||||
@ -425,7 +436,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
FfiSafe
|
||||
|
||||
if all_phantom { FfiPhantom } else { FfiSafe }
|
||||
}
|
||||
AdtKind::Union => {
|
||||
if !cx.lookup_repr_hints(def.did).contains(&attr::ReprExtern) {
|
||||
@ -434,11 +446,20 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
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;
|
||||
}
|
||||
@ -447,7 +468,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
FfiSafe
|
||||
|
||||
if all_phantom { FfiPhantom } else { FfiSafe }
|
||||
}
|
||||
AdtKind::Enum => {
|
||||
if def.variants.is_empty() {
|
||||
@ -498,6 +520,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => {
|
||||
return r;
|
||||
}
|
||||
FfiPhantom => {
|
||||
return FfiBadEnum(def.did,
|
||||
"Found phantom data in enum variant");
|
||||
}
|
||||
FfiUnsafe(s) => {
|
||||
return FfiBadEnum(def.did, s);
|
||||
}
|
||||
@ -591,6 +617,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -1369,14 +1369,14 @@ extern "C" {
|
||||
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;
|
||||
|
||||
@ -1386,7 +1386,7 @@ extern "C" {
|
||||
File: DIFile,
|
||||
LineNumber: c_uint,
|
||||
SizeInBits: u64,
|
||||
AlignInBits: u64,
|
||||
AlignInBits: u32,
|
||||
Flags: DIFlags,
|
||||
DerivedFrom: DIType,
|
||||
Elements: DIArray,
|
||||
@ -1401,7 +1401,7 @@ extern "C" {
|
||||
File: DIFile,
|
||||
LineNo: c_uint,
|
||||
SizeInBits: u64,
|
||||
AlignInBits: u64,
|
||||
AlignInBits: u32,
|
||||
OffsetInBits: u64,
|
||||
Flags: DIFlags,
|
||||
Ty: DIType)
|
||||
@ -1429,7 +1429,7 @@ extern "C" {
|
||||
isLocalToUnit: bool,
|
||||
Val: ValueRef,
|
||||
Decl: DIDescriptor,
|
||||
AlignInBits: u64)
|
||||
AlignInBits: u32)
|
||||
-> DIGlobalVariable;
|
||||
|
||||
pub fn LLVMRustDIBuilderCreateVariable(Builder: DIBuilderRef,
|
||||
@ -1442,19 +1442,19 @@ extern "C" {
|
||||
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;
|
||||
@ -1489,7 +1489,7 @@ extern "C" {
|
||||
File: DIFile,
|
||||
LineNumber: c_uint,
|
||||
SizeInBits: u64,
|
||||
AlignInBits: u64,
|
||||
AlignInBits: u32,
|
||||
Elements: DIArray,
|
||||
ClassType: DIType)
|
||||
-> DIType;
|
||||
@ -1500,7 +1500,7 @@ extern "C" {
|
||||
File: DIFile,
|
||||
LineNumber: c_uint,
|
||||
SizeInBits: u64,
|
||||
AlignInBits: u64,
|
||||
AlignInBits: u32,
|
||||
Flags: DIFlags,
|
||||
Elements: DIArray,
|
||||
RunTimeLang: c_uint,
|
||||
|
@ -27,6 +27,7 @@ use errors::emitter::Emitter;
|
||||
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};
|
||||
@ -754,10 +755,13 @@ pub fn run_passes(sess: &Session,
|
||||
}
|
||||
|
||||
// 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 {
|
||||
|
@ -1783,7 +1783,7 @@ pub fn create_global_var_metadata(cx: &CrateContext,
|
||||
is_local_to_unit,
|
||||
global,
|
||||
ptr::null_mut(),
|
||||
global_align as u64,
|
||||
global_align,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -464,7 +464,7 @@ pub fn declare_local<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
cx.sess().opts.optimize != config::OptLevel::No,
|
||||
DIFlags::FlagZero,
|
||||
argument_index,
|
||||
align as u64,
|
||||
align,
|
||||
)
|
||||
};
|
||||
source_loc::set_debug_location(bcx,
|
||||
|
@ -24,6 +24,8 @@ use type_::Type;
|
||||
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
|
||||
@ -49,12 +51,13 @@ pub fn span_start(cx: &CrateContext, span: Span) -> syntax_pos::Loc {
|
||||
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]
|
||||
|
@ -35,6 +35,7 @@ use std::fmt::{self, Write};
|
||||
use std::slice;
|
||||
use std::str;
|
||||
use syntax::feature_gate::UnstableFeatures;
|
||||
use syntax::codemap::Span;
|
||||
|
||||
use html::render::derive_id;
|
||||
use html::toc::TocBuilder;
|
||||
@ -424,7 +425,7 @@ pub fn render(w: &mut fmt::Formatter,
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
@ -449,11 +450,12 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, start_line:
|
||||
});
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -474,7 +476,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, start_line:
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -18,6 +18,7 @@ use getopts;
|
||||
use testing;
|
||||
use rustc::session::search_paths::SearchPaths;
|
||||
use rustc::session::config::Externs;
|
||||
use syntax::codemap::DUMMY_SP;
|
||||
|
||||
use externalfiles::{ExternalHtml, LoadStringError, load_string};
|
||||
|
||||
@ -154,9 +155,8 @@ pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
|
||||
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
|
||||
|
@ -37,7 +37,7 @@ use rustc_trans::back::link;
|
||||
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;
|
||||
|
||||
@ -97,7 +97,6 @@ pub fn run(input: &str,
|
||||
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,
|
||||
@ -105,7 +104,6 @@ pub fn run(input: &str,
|
||||
false,
|
||||
opts,
|
||||
maybe_sysroot,
|
||||
filename,
|
||||
Some(codemap));
|
||||
|
||||
{
|
||||
@ -391,15 +389,14 @@ pub struct Collector {
|
||||
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(),
|
||||
@ -412,8 +409,7 @@ impl Collector {
|
||||
cratename: cratename,
|
||||
opts: opts,
|
||||
maybe_sysroot: maybe_sysroot,
|
||||
filename: filename,
|
||||
start_line: 0,
|
||||
position: DUMMY_SP,
|
||||
codemap: codemap,
|
||||
}
|
||||
}
|
||||
@ -421,8 +417,8 @@ impl Collector {
|
||||
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();
|
||||
@ -467,16 +463,25 @@ impl Collector {
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -520,7 +525,7 @@ impl<'a, 'hir> HirCollector<'a, 'hir> {
|
||||
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);
|
||||
|
@ -844,9 +844,9 @@ impl Child {
|
||||
/// 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.
|
||||
///
|
||||
@ -857,14 +857,13 @@ impl Child {
|
||||
/// ```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);
|
||||
@ -873,8 +872,8 @@ impl Child {
|
||||
/// }
|
||||
/// ```
|
||||
#[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
|
||||
|
@ -502,17 +502,17 @@ impl Process {
|
||||
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)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ impl Process {
|
||||
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::*;
|
||||
|
||||
@ -179,7 +179,7 @@ impl Process {
|
||||
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); },
|
||||
}
|
||||
@ -192,7 +192,7 @@ impl Process {
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,19 +249,19 @@ impl Process {
|
||||
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)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -340,18 +340,18 @@ impl Process {
|
||||
}
|
||||
}
|
||||
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,11 +60,95 @@
|
||||
//! 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,
|
||||
@ -177,81 +261,6 @@ pub fn mk_printer<'a>(out: Box<io::Write+'a>, linewidth: usize) -> Printer<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// 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,
|
||||
@ -292,7 +301,7 @@ impl<'a> Printer<'a> {
|
||||
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;
|
||||
}
|
||||
@ -571,8 +580,8 @@ impl<'a> Printer<'a> {
|
||||
}
|
||||
|
||||
// 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,
|
||||
@ -580,10 +589,12 @@ pub fn rbox(p: &mut Printer, indent: usize, b: Breaks) -> io::Result<()> {
|
||||
}))
|
||||
}
|
||||
|
||||
/// 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)
|
||||
}
|
||||
|
@ -513,7 +513,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction(
|
||||
|
||||
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)
|
||||
@ -524,7 +524,7 @@ LLVMRustDIBuilderCreateBasicType(LLVMRustDIBuilderRef Builder, const char *Name,
|
||||
|
||||
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));
|
||||
}
|
||||
@ -532,7 +532,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreatePointerType(
|
||||
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) {
|
||||
@ -546,7 +546,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStructType(
|
||||
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,
|
||||
@ -573,7 +573,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable(
|
||||
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)
|
||||
@ -612,7 +612,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable(
|
||||
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(
|
||||
@ -637,7 +637,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable(
|
||||
|
||||
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),
|
||||
@ -646,7 +646,7 @@ LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
|
||||
|
||||
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),
|
||||
@ -687,7 +687,7 @@ LLVMRustDIBuilderCreateEnumerator(LLVMRustDIBuilderRef Builder,
|
||||
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,
|
||||
@ -698,7 +698,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerationType(
|
||||
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,
|
||||
|
@ -29,6 +29,9 @@ pub type RustBadRet = extern fn() -> Box<u32>;
|
||||
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
|
||||
@ -40,6 +43,9 @@ extern {
|
||||
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
|
||||
|
38
src/test/incremental/issue-39569.rs
Normal file
38
src/test/incremental/issue-39569.rs
Normal file
@ -0,0 +1,38 @@
|
||||
// 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;
|
||||
}
|
||||
|
34
src/test/run-pass/issue-34798.rs
Normal file
34
src/test/run-pass/issue-34798.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// 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() {
|
||||
}
|
@ -13,7 +13,6 @@
|
||||
#![feature(process_try_wait)]
|
||||
|
||||
use std::env;
|
||||
use std::io;
|
||||
use std::process::Command;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
@ -32,17 +31,17 @@ fn main() {
|
||||
.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())
|
||||
@ -51,17 +50,17 @@ fn main() {
|
||||
.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());
|
||||
}
|
||||
|
19
src/test/rustdoc/test_option_check/bar.rs
Normal file
19
src/test/rustdoc/test_option_check/bar.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// 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() {}
|
@ -11,6 +11,8 @@
|
||||
// compile-flags: --test
|
||||
// check-test-line-numbers-match
|
||||
|
||||
pub mod bar;
|
||||
|
||||
/// This is a Foo;
|
||||
///
|
||||
/// ```
|
||||
|
@ -11,7 +11,7 @@
|
||||
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};
|
||||
@ -95,7 +95,6 @@ static MINGW: &'static [&'static str] = &[
|
||||
"x86_64-pc-windows-gnu",
|
||||
];
|
||||
|
||||
#[derive(RustcEncodable)]
|
||||
struct Manifest {
|
||||
manifest_version: String,
|
||||
date: String,
|
||||
@ -171,8 +170,18 @@ impl Builder {
|
||||
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);
|
||||
|
@ -30,6 +30,7 @@ use std::io::{self, BufReader};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Output, ExitStatus};
|
||||
use std::str;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use extract_gdb_version;
|
||||
|
||||
@ -1942,17 +1943,28 @@ actual:\n\
|
||||
}
|
||||
}
|
||||
|
||||
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("```") {
|
||||
@ -1966,8 +1978,21 @@ actual:\n\
|
||||
} 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")
|
||||
@ -1975,27 +2000,35 @@ actual:\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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user