From eed46fbb30783e7fce913d4547c04d6e948319eb Mon Sep 17 00:00:00 2001 From: Aisha630 Date: Mon, 20 Jul 2026 18:01:36 -0500 Subject: [PATCH 1/5] ptx: add benchmark --- .github/workflows/benchmarks.yml | 3 +- Cargo.lock | 3 ++ src/uu/ptx/Cargo.toml | 10 +++++ src/uu/ptx/benches/ptx_bench.rs | 73 ++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/uu/ptx/benches/ptx_bench.rs diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index b85f10c5c76..9a9ab11323b 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -65,7 +65,8 @@ jobs: uu_date, uu_csplit, uu_true, - uu_false + uu_false, + uu_ptx ] steps: - uses: actions/checkout@v7.0.0 diff --git a/Cargo.lock b/Cargo.lock index 2712f7b3bf2..b8836032604 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4018,8 +4018,11 @@ name = "uu_ptx" version = "0.9.0" dependencies = [ "clap", + "codspeed-divan-compat", "fluent", "regex", + "rustix", + "tempfile", "thiserror 2.0.19", "uucore", ] diff --git a/src/uu/ptx/Cargo.toml b/src/uu/ptx/Cargo.toml index 83225408a97..93f539cf371 100644 --- a/src/uu/ptx/Cargo.toml +++ b/src/uu/ptx/Cargo.toml @@ -26,6 +26,16 @@ uucore = { workspace = true } thiserror = { workspace = true } fluent = { workspace = true } +[dev-dependencies] +divan = { workspace = true } +rustix = { workspace = true, features = ["stdio", "fs"] } +tempfile = { workspace = true } +uucore = { workspace = true, features = ["benchmark"] } + [[bin]] name = "ptx" path = "src/main.rs" + +[[bench]] +name = "ptx_bench" +harness = false diff --git a/src/uu/ptx/benches/ptx_bench.rs b/src/uu/ptx/benches/ptx_bench.rs new file mode 100644 index 00000000000..88f8f457777 --- /dev/null +++ b/src/uu/ptx/benches/ptx_bench.rs @@ -0,0 +1,73 @@ +// 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. + +//! Benchmarks for `ptx`. +//! +//! Each bench redirects fd 1 onto /dev/null so the (very large) permuted index +//! does not flood the harness's terminal. It is restored after each iteration. + +#[cfg(unix)] +mod benches { + use divan::{Bencher, black_box}; + use tempfile::TempDir; + use uu_ptx::uumain; + use uucore::benchmark::{create_test_file, run_util_function, text_data}; + + fn bench_ptx(bencher: Bencher, data: &[u8], args: &[&str]) { + let temp_dir = TempDir::new().unwrap(); + let file_path = create_test_file(data, temp_dir.path()); + let file_path_str = file_path.to_str().unwrap(); + + let mut full_args: Vec<&str> = args.to_vec(); + full_args.push(file_path_str); + let devnull = std::fs::OpenOptions::new() + .write(true) + .open("/dev/null") + .unwrap(); + let stdout_bak = rustix::io::dup(rustix::stdio::stdout()).unwrap(); + rustix::stdio::dup2_stdout(&devnull).unwrap(); + + bencher.bench_local(|| { + black_box(run_util_function(uumain, &full_args)); + }); + + rustix::stdio::dup2_stdout(&stdout_bak).unwrap(); + } + + /// Build a fixed ~1 MiB input spread across num_lines lines + fn fixed_size_data(num_lines: usize) -> Vec { + let line_len = (1024 * 1024 / num_lines).max(1); + text_data::generate_by_lines(num_lines, line_len) + } + + /// Benchmark the common case of many short lines. + #[divan::bench(args = [100_000])] + fn ptx_many_lines(bencher: Bencher, num_lines: usize) { + let data = text_data::generate_by_lines(num_lines, 80); + bench_ptx(bencher, &data, &[]); + } + + #[divan::bench(args = [1, 10, 100, 1000])] + fn ptx_long_lines(bencher: Bencher, num_lines: usize) { + bench_ptx(bencher, &fixed_size_data(num_lines), &[]); + } + + /// Benchmark -r on many short lines. + #[divan::bench(args = [100_000])] + fn ptx_input_references_many_lines(bencher: Bencher, num_lines: usize) { + let data = text_data::generate_by_lines(num_lines, 80); + bench_ptx(bencher, &data, &["-r"]); + } + + /// Benchmark -r on long lines + #[divan::bench(args = [1, 10, 100, 1000])] + fn ptx_input_references_long_lines(bencher: Bencher, num_lines: usize) { + bench_ptx(bencher, &fixed_size_data(num_lines), &["-r"]); + } +} + +fn main() { + divan::main(); +} From 8924e4262e5c733c76b9f1b07e77a4c0ba4f76ed Mon Sep 17 00:00:00 2001 From: Aisha630 Date: Mon, 20 Jul 2026 18:42:16 -0500 Subject: [PATCH 2/5] ptx: better naming for benchmarks --- src/uu/ptx/benches/ptx_bench.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/uu/ptx/benches/ptx_bench.rs b/src/uu/ptx/benches/ptx_bench.rs index 88f8f457777..1d412a2f815 100644 --- a/src/uu/ptx/benches/ptx_bench.rs +++ b/src/uu/ptx/benches/ptx_bench.rs @@ -6,7 +6,7 @@ //! Benchmarks for `ptx`. //! //! Each bench redirects fd 1 onto /dev/null so the (very large) permuted index -//! does not flood the harness's terminal. It is restored after each iteration. +//! does not flood the harness's terminal. It is restored afterwards. #[cfg(unix)] mod benches { @@ -44,7 +44,7 @@ mod benches { /// Benchmark the common case of many short lines. #[divan::bench(args = [100_000])] - fn ptx_many_lines(bencher: Bencher, num_lines: usize) { + fn ptx_short_lines(bencher: Bencher, num_lines: usize) { let data = text_data::generate_by_lines(num_lines, 80); bench_ptx(bencher, &data, &[]); } @@ -56,7 +56,7 @@ mod benches { /// Benchmark -r on many short lines. #[divan::bench(args = [100_000])] - fn ptx_input_references_many_lines(bencher: Bencher, num_lines: usize) { + fn ptx_input_references_short_lines(bencher: Bencher, num_lines: usize) { let data = text_data::generate_by_lines(num_lines, 80); bench_ptx(bencher, &data, &["-r"]); } From 71ab31921a88d63d14bd2614a01006bc9be8548b Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 21 Jul 2026 09:41:57 +0200 Subject: [PATCH 3/5] Update src/uu/ptx/benches/ptx_bench.rs --- src/uu/ptx/benches/ptx_bench.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/ptx/benches/ptx_bench.rs b/src/uu/ptx/benches/ptx_bench.rs index 1d412a2f815..dec23e7b1cb 100644 --- a/src/uu/ptx/benches/ptx_bench.rs +++ b/src/uu/ptx/benches/ptx_bench.rs @@ -49,7 +49,7 @@ mod benches { bench_ptx(bencher, &data, &[]); } - #[divan::bench(args = [1, 10, 100, 1000])] + #[divan::bench(args = [1000])] fn ptx_long_lines(bencher: Bencher, num_lines: usize) { bench_ptx(bencher, &fixed_size_data(num_lines), &[]); } From 52bf2894e109fa1d226a708bbed419dd91e56013 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 21 Jul 2026 09:42:20 +0200 Subject: [PATCH 4/5] Update src/uu/ptx/benches/ptx_bench.rs --- src/uu/ptx/benches/ptx_bench.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/ptx/benches/ptx_bench.rs b/src/uu/ptx/benches/ptx_bench.rs index dec23e7b1cb..be992ff21fd 100644 --- a/src/uu/ptx/benches/ptx_bench.rs +++ b/src/uu/ptx/benches/ptx_bench.rs @@ -62,7 +62,7 @@ mod benches { } /// Benchmark -r on long lines - #[divan::bench(args = [1, 10, 100, 1000])] + #[divan::bench(args = [1000])] fn ptx_input_references_long_lines(bencher: Bencher, num_lines: usize) { bench_ptx(bencher, &fixed_size_data(num_lines), &["-r"]); } From c4abf8e078aab70f1b4f607ca700d24a85931241 Mon Sep 17 00:00:00 2001 From: Aisha630 Date: Tue, 21 Jul 2026 11:51:26 -0500 Subject: [PATCH 5/5] ptx: use std instead of rustix in benchmark --- Cargo.lock | 2 - src/uu/ptx/Cargo.toml | 2 - src/uu/ptx/benches/ptx_bench.rs | 91 ++++++++++++++------------------- 3 files changed, 38 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8836032604..0a9c0640127 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4021,8 +4021,6 @@ dependencies = [ "codspeed-divan-compat", "fluent", "regex", - "rustix", - "tempfile", "thiserror 2.0.19", "uucore", ] diff --git a/src/uu/ptx/Cargo.toml b/src/uu/ptx/Cargo.toml index 93f539cf371..131d46382a4 100644 --- a/src/uu/ptx/Cargo.toml +++ b/src/uu/ptx/Cargo.toml @@ -28,8 +28,6 @@ fluent = { workspace = true } [dev-dependencies] divan = { workspace = true } -rustix = { workspace = true, features = ["stdio", "fs"] } -tempfile = { workspace = true } uucore = { workspace = true, features = ["benchmark"] } [[bin]] diff --git a/src/uu/ptx/benches/ptx_bench.rs b/src/uu/ptx/benches/ptx_bench.rs index be992ff21fd..5bdbbe1d7d0 100644 --- a/src/uu/ptx/benches/ptx_bench.rs +++ b/src/uu/ptx/benches/ptx_bench.rs @@ -4,68 +4,53 @@ // file that was distributed with this source code. //! Benchmarks for `ptx`. -//! -//! Each bench redirects fd 1 onto /dev/null so the (very large) permuted index -//! does not flood the harness's terminal. It is restored afterwards. -#[cfg(unix)] -mod benches { - use divan::{Bencher, black_box}; - use tempfile::TempDir; - use uu_ptx::uumain; - use uucore::benchmark::{create_test_file, run_util_function, text_data}; +use divan::{Bencher, black_box}; +use uu_ptx::uumain; +use uucore::benchmark::{run_util_function, setup_test_file, text_data}; - fn bench_ptx(bencher: Bencher, data: &[u8], args: &[&str]) { - let temp_dir = TempDir::new().unwrap(); - let file_path = create_test_file(data, temp_dir.path()); - let file_path_str = file_path.to_str().unwrap(); +fn bench_ptx(bencher: Bencher, data: &[u8], args: &[&str]) { + let file_path = setup_test_file(data); + let file_path_str = file_path.to_str().unwrap(); - let mut full_args: Vec<&str> = args.to_vec(); - full_args.push(file_path_str); - let devnull = std::fs::OpenOptions::new() - .write(true) - .open("/dev/null") - .unwrap(); - let stdout_bak = rustix::io::dup(rustix::stdio::stdout()).unwrap(); - rustix::stdio::dup2_stdout(&devnull).unwrap(); + let mut full_args: Vec<&str> = args.to_vec(); + full_args.push(file_path_str); - bencher.bench_local(|| { - black_box(run_util_function(uumain, &full_args)); - }); - - rustix::stdio::dup2_stdout(&stdout_bak).unwrap(); - } + bencher.bench(|| { + black_box(run_util_function(uumain, &full_args)); + }); +} - /// Build a fixed ~1 MiB input spread across num_lines lines - fn fixed_size_data(num_lines: usize) -> Vec { - let line_len = (1024 * 1024 / num_lines).max(1); - text_data::generate_by_lines(num_lines, line_len) - } +/// Build a fixed ~1 MiB input spread across num_lines lines. +fn fixed_size_data(num_lines: usize) -> Vec { + let line_len = (1024 * 1024 / num_lines).max(1); + text_data::generate_by_lines(num_lines, line_len) +} - /// Benchmark the common case of many short lines. - #[divan::bench(args = [100_000])] - fn ptx_short_lines(bencher: Bencher, num_lines: usize) { - let data = text_data::generate_by_lines(num_lines, 80); - bench_ptx(bencher, &data, &[]); - } +/// Benchmark the common case of many short lines. +#[divan::bench(args = [100_000])] +fn ptx_short_lines(bencher: Bencher, num_lines: usize) { + let data = text_data::generate_by_lines(num_lines, 80); + bench_ptx(bencher, &data, &[]); +} - #[divan::bench(args = [1000])] - fn ptx_long_lines(bencher: Bencher, num_lines: usize) { - bench_ptx(bencher, &fixed_size_data(num_lines), &[]); - } +/// Benchmark a fixed ~1 MiB input spread across 100 lines. +#[divan::bench(args = [100])] +fn ptx_long_lines(bencher: Bencher, num_lines: usize) { + bench_ptx(bencher, &fixed_size_data(num_lines), &[]); +} - /// Benchmark -r on many short lines. - #[divan::bench(args = [100_000])] - fn ptx_input_references_short_lines(bencher: Bencher, num_lines: usize) { - let data = text_data::generate_by_lines(num_lines, 80); - bench_ptx(bencher, &data, &["-r"]); - } +/// Benchmark -r on many short lines. +#[divan::bench(args = [100_000])] +fn ptx_input_references_short_lines(bencher: Bencher, num_lines: usize) { + let data = text_data::generate_by_lines(num_lines, 80); + bench_ptx(bencher, &data, &["-r"]); +} - /// Benchmark -r on long lines - #[divan::bench(args = [1000])] - fn ptx_input_references_long_lines(bencher: Bencher, num_lines: usize) { - bench_ptx(bencher, &fixed_size_data(num_lines), &["-r"]); - } +/// Benchmark -r on long lines +#[divan::bench(args = [100])] +fn ptx_input_references_long_lines(bencher: Bencher, num_lines: usize) { + bench_ptx(bencher, &fixed_size_data(num_lines), &["-r"]); } fn main() {