Skip to content

Instantly share code, notes, and snippets.

@leo60228
Created June 8, 2019 17:05
Show Gist options
  • Save leo60228/f00e4867f5f14019ee5dea93175ddeed to your computer and use it in GitHub Desktop.
Save leo60228/f00e4867f5f14019ee5dea93175ddeed to your computer and use it in GitHub Desktop.
#![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);
@yuyoyuppe
Copy link

yuyoyuppe commented Nov 12, 2019

What about stuff like that? Currently Rust seems to only do length dispatch optimization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment