diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 1ffce535dae..35f870086e2 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -46,6 +46,7 @@ jobs: - { package: uu_uniq } - { package: uu_wc } - { package: uu_factor } + - { package: uu_date } steps: - uses: actions/checkout@v6 with: diff --git a/Cargo.lock b/Cargo.lock index 909c0351005..f540293b72c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3188,10 +3188,12 @@ name = "uu_date" version = "0.5.0" dependencies = [ "clap", + "codspeed-divan-compat", "fluent", "jiff", "nix", "parse_datetime", + "tempfile", "uucore", "windows-sys 0.61.2", ] diff --git a/src/uu/date/Cargo.toml b/src/uu/date/Cargo.toml index 431868b9175..9bff97696f0 100644 --- a/src/uu/date/Cargo.toml +++ b/src/uu/date/Cargo.toml @@ -41,3 +41,12 @@ windows-sys = { workspace = true, features = [ [[bin]] name = "date" path = "src/main.rs" + +[dev-dependencies] +divan = { workspace = true } +tempfile = { workspace = true } +uucore = { workspace = true, features = ["benchmark"] } + +[[bench]] +name = "date_bench" +harness = false diff --git a/src/uu/date/benches/date_bench.rs b/src/uu/date/benches/date_bench.rs new file mode 100644 index 00000000000..636f876c544 --- /dev/null +++ b/src/uu/date/benches/date_bench.rs @@ -0,0 +1,76 @@ +// 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 std::io::Write; +use tempfile::NamedTempFile; +use uu_date::uumain; +use uucore::benchmark::run_util_function; + +/// Helper to create a temporary file containing N lines of date strings. +fn setup_date_file(lines: usize, date_format: &str) -> NamedTempFile { + let mut file = NamedTempFile::new().unwrap(); + for _ in 0..lines { + writeln!(file, "{date_format}").unwrap(); + } + file +} + +/// Benchmarks processing a file containing simple ISO dates. +#[divan::bench(args = [100, 1_000, 10_000])] +fn file_iso_dates(bencher: Bencher, count: usize) { + let file = setup_date_file(count, "2023-05-10 12:00:00"); + let path = file.path().to_str().unwrap(); + + bencher.bench(|| { + black_box(run_util_function(uumain, &["-f", path])); + }); +} + +/// Benchmarks processing a file containing dates with Timezone abbreviations. +#[divan::bench(args = [100, 1_000, 10_000])] +fn file_tz_abbreviations(bencher: Bencher, count: usize) { + // "EST" triggers the abbreviation lookup and double-parsing logic + let file = setup_date_file(count, "2023-05-10 12:00:00 EST"); + let path = file.path().to_str().unwrap(); + + bencher.bench(|| { + black_box(run_util_function(uumain, &["-f", path])); + }); +} + +/// Benchmarks formatting speed using a custom output format. +#[divan::bench(args = [1_000])] +fn file_custom_format(bencher: Bencher, count: usize) { + let file = setup_date_file(count, "2023-05-10 12:00:00"); + let path = file.path().to_str().unwrap(); + + bencher.bench(|| { + black_box(run_util_function(uumain, &["-f", path, "+%A %d %B %Y"])); + }); +} + +/// Benchmarks the overhead of starting the utility for a single date (no file). +#[divan::bench] +fn single_date_now(bencher: Bencher) { + bencher.bench(|| { + black_box(run_util_function(uumain, &[])); + }); +} + +/// Benchmarks parsing a complex relative date string passed as an argument. +#[divan::bench] +fn complex_relative_date(bencher: Bencher) { + bencher.bench(|| { + black_box(run_util_function( + uumain, + &["--date=last friday 12:00 + 2 days"], + )); + }); +} + +fn main() { + divan::main(); +}