Skip to content

Instantly share code, notes, and snippets.

@kennytm
Created May 15, 2017 08:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kennytm/2b6264fdf67651db78cb37095b037fae to your computer and use it in GitHub Desktop.
Save kennytm/2b6264fdf67651db78cb37095b037fae to your computer and use it in GitHub Desktop.
Benchmark for issue #41993.
#![feature(drop_types_in_const)]
#![feature(test)]
#![feature(rand)] // to be incorporated into libcore, so not using crates.io
#![feature(pattern)]
extern crate test;
extern crate rand;
use test::{Bencher, black_box};
use rand::{XorShiftRng, SeedableRng};
use rand::distributions::{Range, IndependentSample};
use std::str::pattern::*;
struct Literally {
utf8: [u8; 4],
len: u32,
}
struct LiteralSearcher;
unsafe impl<'a> Searcher<'a> for LiteralSearcher {
fn haystack(&self) -> &'a str { unimplemented!() }
fn next(&mut self) -> SearchStep { unimplemented!() }
}
impl Literally {
pub fn new(c: char) -> Literally {
let mut buff = [0; 4];
let len = c.encode_utf8(&mut buff).len() as u32;
Literally {
utf8: buff,
len: len,
}
}
}
impl<'a> Pattern<'a> for Literally {
type Searcher = LiteralSearcher;
fn into_searcher(self, _: &'a str) -> Self::Searcher { unimplemented!() }
fn is_prefix_of(self, haystack: &'a str) -> bool {
haystack.as_bytes().starts_with(&self.utf8[.. self.len as usize])
}
}
#[bench]
fn bench_baseline(b: &mut Bencher) {
for_each_random_string(b, |s| s);
}
// The following 3 tests should have similar performance.
#[bench]
fn bench_start_with_ascii_single_str(b: &mut Bencher) {
for_each_random_string(b, |s| s.starts_with("E"));
}
#[bench]
fn bench_start_with_ascii_as_bytes(b: &mut Bencher) {
for_each_random_string(b, |s| s.as_bytes().starts_with(b"E"));
}
#[bench]
fn bench_start_with_ascii_char(b: &mut Bencher) {
for_each_random_string(b, |s| s.starts_with('E'));
}
#[bench]
fn bench_start_with_literal_char(b: &mut Bencher) {
for_each_random_string(b, |s| s.starts_with(Literally::new('E')));
}
const TEST_LEN: usize = 100000;
const CORPUS: &[&str] = &[
"Since the Rust compiler is written in Rust, it must be built by a",
"precompiled \"snapshot\" version of itself (made in an earlier state of",
"development). As such, source builds require a connection to the Internet, to",
"fetch snapshots, and an OS that can execute the available snapshot binaries.",
"Snapshot binaries are currently built and tested on several platforms:",
"| Platform / Architecture | x86 | x86_64 |",
"|--------------------------------|-----|--------|",
"| Windows (7, 8, Server 2008 R2) | ✓ | ✓ |",
"| Linux (2.6.18 or later) | ✓ | ✓ |",
"| OSX (10.7 Lion or later) | ✓ | ✓ |",
"You may find that other platforms work, but these are our officially",
"supported build environments that are most likely to work.",
"Rust currently needs between 600MiB and 1.5GiB to build, depending on platform.",
"If it hits swap, it will take a very long time to build.",
"",
"This code is editable and runnable!",
"Este código es editable y ejecutable!",
"Ce code est modifiable et exécutable!",
"Questo codice è modificabile e eseguibile!",
"このコードは編集して実行出来ます!",
"여기에서 코드를 수정하고 실행할 수 있습니다!",
"Ten kod można edytować oraz uruchomić!",
"Esse código é editável e executável!",
"Этот код можно отредактировать и запустить!",
"Bạn có thể edit và run code trực tiếp!",
"这段代码是可以编辑并且能够运行的!",
"👉🖥⌨️✅📝🛠👌🏃🚀👍💯❤️👏",
];
static mut RANDOMIZED_TEST_SAMPLE: Option<Vec<&str>> = None;
#[inline]
fn for_each_random_string<R, F: FnMut(&'static str) -> R>(b: &mut Bencher, mut f: F) {
// This is safe --- we rely on benchmarks being run in one thread only
// (don't wanna bring in std::sync here...)
let randomized_test_sample = unsafe {
if RANDOMIZED_TEST_SAMPLE.is_none() {
let mut rng = XorShiftRng::from_seed([985435577, 1956560574, 180690316, 2476157442]);
let range = Range::new(0, CORPUS.len());
let mut test_cases = Vec::<&str>::with_capacity(TEST_LEN);
for _ in 0 .. TEST_LEN {
test_cases.push(&CORPUS[range.ind_sample(&mut rng)]);
}
RANDOMIZED_TEST_SAMPLE = Some(test_cases);
}
RANDOMIZED_TEST_SAMPLE.as_ref().unwrap()
};
b.iter(|| for test_case in randomized_test_sample {
black_box(f(test_case));
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment