Skip to content

Instantly share code, notes, and snippets.

@bronson
Last active March 24, 2017 02:06
Show Gist options
  • Save bronson/b4eea6c641ead9e0271ea5f692fbf786 to your computer and use it in GitHub Desktop.
Save bronson/b4eea6c641ead9e0271ea5f692fbf786 to your computer and use it in GitHub Desktop.
benchmark splitting some strings in half (precompiling regexes)
$ rustc -L target/release/deps --test src/bench.rs && ./bench --bench
running 5 tests
test tests::bench_using_indexing ... bench: 1,674 ns/iter (+/- 69)
test tests::bench_using_regex_index ... bench: 249 ns/iter (+/- 20)
test tests::bench_using_regex_next ... bench: 134 ns/iter (+/- 7)
test tests::bench_using_regex_vec ... bench: 532 ns/iter (+/- 66)
test tests::bench_using_window ... bench: 964 ns/iter (+/- 39)
test result: ok. 0 passed; 0 failed; 0 ignored; 5 measured
// To run this benchmark:
//
// rustc -L target/release/deps --test src/bench.rs && ./bench --bench
//
// You must have the needed crates in target/release/deps, of course.
#![feature(test)]
#[macro_use]
extern crate lazy_static;
extern crate test;
extern crate regex;
pub fn using_regex_vec(s: &str) -> (&str, &str) {
lazy_static! {
static ref RE: regex::Regex = regex::Regex::new(r":\D").unwrap();
}
let result: Vec<_> = RE.splitn(s, 2).collect();
(result[0], result[1])
}
pub fn using_regex_next(s: &str) -> (&str, &str) {
lazy_static! {
static ref RE: regex::Regex = regex::Regex::new(r":\D").unwrap();
}
let mut result = RE.splitn(s, 2);
(result.next().unwrap(), result.next().unwrap())
}
fn using_regex_index(s: &str) -> (&str, &str) {
lazy_static! {
static ref RE: regex::Regex = regex::Regex::new(r":\D").unwrap();
}
let i = RE.find(s).unwrap().start();
let (r0, r1) = s.split_at(i);
(r0, &r1[1..]) // exclude the ':'
}
pub fn using_window(s: &str) -> (&str, &str) {
let i = s.as_bytes().windows(2)
.position(|w| w[0] == b':' && !(w[1] as char).is_digit(10))
.unwrap();
s.split_at(i)
}
pub fn using_indexing(s: &str) -> (&str, &str) {
let n = s.len();
let i = s[..n-1].char_indices()
.find(|&(i, c)| c == ':' && !s[i+1..].starts_with(|c| char::is_digit(c, 10)))
.unwrap().0;
s.split_at(i)
}
#[cfg(test)]
mod tests {
use super::*;
use test::Bencher;
#[bench]
fn bench_using_regex_vec(b: &mut Bencher) {
assert_eq!(("a:0hello", "world"), using_regex_vec("a:0hello: world"));
b.iter(|| using_regex_vec("a:0hello: world"));
}
#[bench]
fn bench_using_regex_next(b: &mut Bencher) {
assert_eq!(("a:0hello", "world"), using_regex_next("a:0hello: world"));
b.iter(|| using_regex_next("a:0hello: world"));
}
#[bench]
fn bench_using_regex_index(b: &mut Bencher) {
assert_eq!(("a:0hello", " world"), using_regex_index("a:0hello: world"));
b.iter(|| using_regex_index("a:0hello: world"));
}
#[bench]
fn bench_using_window(b: &mut Bencher) {
assert_eq!(("a:0hello", ": world"), using_window("a:0hello: world"));
b.iter(|| using_window("a:0hello: world"));
}
#[bench]
fn bench_using_indexing(b: &mut Bencher) {
assert_eq!(("a:0hello", ": world"), using_indexing("a:0hello: world"));
b.iter(|| using_indexing("a:0hello: world"));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment