Created
June 8, 2019 17:05
-
-
Save leo60228/f00e4867f5f14019ee5dea93175ddeed to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(proc_macro_hygiene)] | |
use criterion::Criterion; | |
use criterion::ParameterizedBenchmark; | |
use criterion::{criterion_group, criterion_main}; | |
use unicase::Ascii; | |
use strum_macros::EnumString; | |
use phf::phf_map; | |
#[derive(EnumString, Clone, Copy)] | |
enum Test { | |
Aa, | |
Ab, | |
Ccc, | |
Cd, | |
D, | |
} | |
static SENSITIVE_PHF: phf::Map<&'static str, Test> = phf_map! { | |
"Aa" => Test::Aa, | |
"Ab" => Test::Ab, | |
"Ccc" => Test::Ccc, | |
"Cd" => Test::Cd, | |
"D" => Test::D, | |
}; | |
static LOWERCASE_PHF: phf::Map<&'static str, Test> = phf_map! { | |
"aa" => Test::Aa, | |
"ab" => Test::Ab, | |
"ccc" => Test::Ccc, | |
"cd" => Test::Cd, | |
"d" => Test::D, | |
}; | |
fn case_sensitive_phf(string: &str) -> Option<Test> { | |
SENSITIVE_PHF.get(string).cloned() | |
} | |
fn lowercase_phf(string: &str) -> Option<Test> { | |
LOWERCASE_PHF.get::<str>(string.to_ascii_lowercase().as_ref()).cloned() | |
} | |
fn case_sensitive_strum(string: &str) -> Option<Test> { | |
string.parse().ok() | |
} | |
fn case_sensitive_match(string: &str) -> Option<Test> { | |
match string { | |
"Aa" => Some(Test::Aa), | |
"Ab" => Some(Test::Ab), | |
"Ccc" => Some(Test::Ccc), | |
"Cd" => Some(Test::Cd), | |
"D" => Some(Test::D), | |
_ => None, | |
} | |
} | |
fn lowercase_match(string: &str) -> Option<Test> { | |
match string.to_ascii_lowercase().as_ref() { | |
"aa" => Some(Test::Aa), | |
"ab" => Some(Test::Ab), | |
"ccc" => Some(Test::Ccc), | |
"cd" => Some(Test::Cd), | |
"d" => Some(Test::D), | |
_ => None, | |
} | |
} | |
fn lowercase_match_len(string: &str) -> Option<Test> { | |
let lowercase = string.to_ascii_lowercase(); | |
match string.len() { | |
2 if lowercase == "aa" => Some(Test::Aa), | |
2 if lowercase == "ab" => Some(Test::Ab), | |
3 if lowercase == "ccc" => Some(Test::Ccc), | |
2 if lowercase == "cd" => Some(Test::Cd), | |
1 if lowercase == "d" => Some(Test::D), | |
_ => None, | |
} | |
} | |
fn lowercase_elif(string: &str) -> Option<Test> { | |
let lowercase = string.to_ascii_lowercase(); | |
if lowercase == "aa" { | |
Some(Test::Aa) | |
} else if lowercase == "ab" { | |
Some(Test::Ab) | |
} else if lowercase == "ccc" { | |
Some(Test::Ccc) | |
} else if lowercase == "cd" { | |
Some(Test::Cd) | |
} else if lowercase == "d" { | |
Some(Test::D) | |
} else { | |
None | |
} | |
} | |
fn case_insensitive_elif(string: &str) -> Option<Test> { | |
if string.eq_ignore_ascii_case("aa") { | |
Some(Test::Aa) | |
} else if string.eq_ignore_ascii_case("ab") { | |
Some(Test::Ab) | |
} else if string.eq_ignore_ascii_case("ccc") { | |
Some(Test::Ccc) | |
} else if string.eq_ignore_ascii_case("cd") { | |
Some(Test::Cd) | |
} else if string.eq_ignore_ascii_case("d") { | |
Some(Test::D) | |
} else { | |
None | |
} | |
} | |
fn unicase_ascii_elif(string: &str) -> Option<Test> { | |
let unicase_ascii = Ascii::new(string); | |
if unicase_ascii == "aa" { | |
Some(Test::Aa) | |
} else if unicase_ascii == "ab" { | |
Some(Test::Ab) | |
} else if unicase_ascii == "ccc" { | |
Some(Test::Ccc) | |
} else if unicase_ascii == "cd" { | |
Some(Test::Cd) | |
} else if unicase_ascii == "d" { | |
Some(Test::D) | |
} else { | |
None | |
} | |
} | |
fn unicase_ascii_match_len(string: &str) -> Option<Test> { | |
let unicase_ascii = Ascii::new(string); | |
match string.len() { | |
2 if unicase_ascii == "aa" => Some(Test::Aa), | |
2 if unicase_ascii == "ab" => Some(Test::Ab), | |
3 if unicase_ascii == "ccc" => Some(Test::Ccc), | |
2 if unicase_ascii == "cd" => Some(Test::Cd), | |
1 if unicase_ascii == "d" => Some(Test::D), | |
_ => None, | |
} | |
} | |
fn criterion_benchmark(c: &mut Criterion) { | |
const NAMES: [&str; 6] = ["Aa", "Ab", "Ccc", "Cd", "D", "Fake"]; | |
c.bench("Case Sensitive", ParameterizedBenchmark::new("PHF", |b, i| b.iter(|| case_sensitive_phf(i)), &NAMES) | |
.with_function("Strum", |b, i| b.iter(|| case_sensitive_strum(i))) | |
.with_function("Simple Match", |b, i| b.iter(|| case_sensitive_match(i)))); | |
c.bench("Case Insensitive", ParameterizedBenchmark::new("Lowercased PHF", |b, i| b.iter(|| lowercase_phf(i)), &NAMES) | |
.with_function("Lowercased Simple Match", |b, i| b.iter(|| lowercase_match(i))) | |
.with_function("Lowercased Match on Length", |b, i| b.iter(|| lowercase_match_len(i))) | |
.with_function("Lowercased If/Else-If Chain", |b, i| b.iter(|| lowercase_elif(i))) | |
.with_function("Case Insensitive If/Else-If Chain", |b, i| b.iter(|| case_insensitive_elif(i))) | |
.with_function("unicase::Ascii If/Else-If Chain", |b, i| b.iter(|| unicase_ascii_elif(i))) | |
.with_function("unicase::Ascii Match on Length", |b, i| b.iter(|| unicase_ascii_match_len(i)))); | |
} | |
criterion_group!(benches, criterion_benchmark); | |
criterion_main!(benches); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What about stuff like that? Currently Rust seems to only do length dispatch optimization.