From 7e90ed21086d504c15d6147edf6decc831c0cad0 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Fri, 25 Aug 2023 19:01:48 -0500 Subject: [PATCH] Add benchmarks with brunch --- .gitignore | 1 + .helix/config.toml | 2 +- bench/Cargo.lock | 62 ++++++++++++++++++++++++++++++++++++++++++++++ bench/Cargo.toml | 11 ++++++++ bench/README.md | 3 +++ bench/src/main.rs | 60 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 bench/Cargo.lock create mode 100644 bench/Cargo.toml create mode 100644 bench/README.md create mode 100644 bench/src/main.rs diff --git a/.gitignore b/.gitignore index 9588052..8f4e85c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target /result /.direnv/ +/bench/target diff --git a/.helix/config.toml b/.helix/config.toml index ef7f507..8c49dda 100644 --- a/.helix/config.toml +++ b/.helix/config.toml @@ -1 +1 @@ -editor.workspace-lsp-roots = ["examples"] +editor.workspace-lsp-roots = ["examples", "bench"] diff --git a/bench/Cargo.lock b/bench/Cargo.lock new file mode 100644 index 0000000..cbc26ad --- /dev/null +++ b/bench/Cargo.lock @@ -0,0 +1,62 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "benches" +version = "0.1.0" +dependencies = [ + "brunch", + "spellbook", + "xdg", +] + +[[package]] +name = "brunch" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ec8866ee8d4ec8c0770203322d7cfa2d2183b03fc788611c5ffc191f2a5688" +dependencies = [ + "dactyl", + "unicode-width", +] + +[[package]] +name = "dactyl" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f762271c6826d426c3fd2e37aa827fa039596bc7050e9289cb713265be3d7f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", +] + +[[package]] +name = "spellbook" +version = "0.1.0" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "xdg" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" diff --git a/bench/Cargo.toml b/bench/Cargo.toml new file mode 100644 index 0000000..a5a4906 --- /dev/null +++ b/bench/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "benches" +version = "0.1.0" +edition = "2021" +# Needed for `std::hint::black_box`. +rust-version = "1.66" + +[dependencies] +spellbook = { path = "../" } +brunch = "0.5" +xdg = "2.5" diff --git a/bench/README.md b/bench/README.md new file mode 100644 index 0000000..ec91d59 --- /dev/null +++ b/bench/README.md @@ -0,0 +1,3 @@ +Benchmarks for the spellbook API. Requires Rust 1.66 or higher. + +Run with `cargo run --release` in this `bench` directory. diff --git a/bench/src/main.rs b/bench/src/main.rs new file mode 100644 index 0000000..7e9659b --- /dev/null +++ b/bench/src/main.rs @@ -0,0 +1,60 @@ +use std::hint::black_box; + +use brunch::Bench; +use spellbook::Dictionary; + +const SAMPLES: u32 = 500_000; + +fn main() { + let base = xdg::BaseDirectories::new().expect("Could not determine XDG directories"); + let (dic_path, aff_path) = match base.get_data_dirs().iter().find_map(|dir| { + let subdir = dir.join("hunspell"); + if !subdir.is_dir() { + return None; + } + + let dic = subdir.join("en_US.dic"); + let aff = subdir.join("en_US.aff"); + if dic.is_file() && aff.is_file() { + Some((dic, aff)) + } else { + None + } + }) { + Some((dic, aff)) => (dic, aff), + None => { + eprintln!("Could not find the en_US dictionary"); + std::process::exit(1); + } + }; + let dic_text = std::fs::read_to_string(dic_path).unwrap(); + let aff_text = std::fs::read_to_string(aff_path).unwrap(); + let dict = Dictionary::compile(&aff_text, &dic_text).unwrap(); + + eprintln!("Starting benchmarks..."); + eprintln!(); + let now = std::time::Instant::now(); + brunch::benches!( + inline: + + // Compilation + Bench::new("Compile en_US") + .run(|| Dictionary::compile(black_box(&aff_text), black_box(&dic_text))), + Bench::spacer(), + + // Checking + Bench::new("In-dictionary word (\"drink\")") + .with_samples(SAMPLES) + .run(|| dict.check(black_box("drink"))), + Bench::new("Word with a suffix (\"drinkable\")") + .with_samples(SAMPLES) + .run(|| dict.check(black_box("drinkable"))), + Bench::new("Multi-affix (\"undrinkable\")") + .with_samples(SAMPLES) + .run(|| dict.check(black_box("undrinkable"))), + Bench::new("Incorrect prefix (\"undrink\")") + .with_samples(SAMPLES) + .run(|| dict.check(black_box("undrink"))), + ); + eprintln!("Finished in {:.1}s", now.elapsed().as_secs_f64()); +}