diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index c43c59718..a85ebd9a8 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -38,6 +38,7 @@ jobs: uu_du, uu_echo, uu_expand, + uu_expr, uu_fold, uu_hostname, uu_join, diff --git a/Cargo.lock b/Cargo.lock index e635bb7a6..bcdc4f572 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3521,6 +3521,7 @@ name = "uu_expr" version = "0.9.0" dependencies = [ "clap", + "codspeed-divan-compat", "fluent", "num-bigint", "num-traits", diff --git a/src/uu/expr/Cargo.toml b/src/uu/expr/Cargo.toml index fd87f3189..9206aa0ed 100644 --- a/src/uu/expr/Cargo.toml +++ b/src/uu/expr/Cargo.toml @@ -27,6 +27,14 @@ uucore = { workspace = true, features = ["i18n-collator"] } thiserror = { workspace = true } fluent = { workspace = true } +[dev-dependencies] +divan = { workspace = true } +uucore = { workspace = true, features = ["benchmark"] } + [[bin]] name = "expr" path = "src/main.rs" + +[[bench]] +name = "expr_bench" +harness = false diff --git a/src/uu/expr/benches/expr_bench.rs b/src/uu/expr/benches/expr_bench.rs new file mode 100644 index 000000000..4be69c3c4 --- /dev/null +++ b/src/uu/expr/benches/expr_bench.rs @@ -0,0 +1,37 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +use divan::{Bencher, black_box}; +use uu_expr::uumain; +use uucore::benchmark::run_util_function; + +/// Benchmark `expr index` worst case: the needle char set never matches, so the +/// whole string is scanned. This is the input that exercised the old O(N * M) +/// behavior. +#[divan::bench] +fn index_no_match(bencher: Bencher) { + let left = "A".repeat(100_000); + let right = "B".repeat(100_000); + + bencher.bench(|| { + black_box(run_util_function(uumain, &["index", &left, &right])); + }); +} + +/// Benchmark `expr index` with a match near the end of the string. +#[divan::bench] +fn index_match_at_end(bencher: Bencher) { + let mut left = "A".repeat(100_000); + left.push('Z'); + let right = "Z".repeat(100_000); + + bencher.bench(|| { + black_box(run_util_function(uumain, &["index", &left, &right])); + }); +} + +fn main() { + divan::main(); +}