Skip to content

Commit 7dbeb8f

Browse files
authored
Merge pull request #8726 from sylvestre/perf-fmt
numfmt: add benchmark
2 parents 1e149b0 + 2ed2157 commit 7dbeb8f

File tree

4 files changed

+132
-1
lines changed

4 files changed

+132
-1
lines changed

.github/workflows/CICD.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1327,6 +1327,6 @@ jobs:
13271327
echo "Running benchmarks for packages: ${{ steps.benchmark_list.outputs.benchmark_packages }}"
13281328
for package in ${{ steps.benchmark_list.outputs.benchmark_packages }}; do
13291329
echo "Running benchmarks for $package"
1330-
cargo codspeed run -p $package
1330+
cargo codspeed run -p $package > /dev/null
13311331
done
13321332
token: ${{ secrets.CODSPEED_TOKEN }}

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/uu/numfmt/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ uucore = { workspace = true, features = ["parser", "ranges"] }
2323
thiserror = { workspace = true }
2424
fluent = { workspace = true }
2525

26+
[dev-dependencies]
27+
divan = { workspace = true }
28+
tempfile = { workspace = true }
29+
uucore = { workspace = true, features = ["benchmark"] }
30+
2631
[[bin]]
2732
name = "numfmt"
2833
path = "src/main.rs"
34+
35+
[[bench]]
36+
name = "numfmt_bench"
37+
harness = false
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
// This file is part of the uutils coreutils package.
2+
//
3+
// For the full copyright and license information, please view the LICENSE
4+
// file that was distributed with this source code.
5+
6+
use divan::{Bencher, black_box};
7+
use tempfile::TempDir;
8+
use uu_numfmt::uumain;
9+
use uucore::benchmark::{create_test_file, run_util_function};
10+
11+
/// Generate numeric data for benchmarking
12+
fn generate_numbers(count: usize) -> String {
13+
(1..=count)
14+
.map(|n| n.to_string())
15+
.collect::<Vec<_>>()
16+
.join("\n")
17+
}
18+
19+
/// Setup benchmark environment with test data
20+
fn setup_benchmark(data: String) -> (TempDir, String) {
21+
let temp_dir = tempfile::tempdir().unwrap();
22+
let file_path = create_test_file(data.as_bytes(), temp_dir.path());
23+
let file_path_str = file_path.to_str().unwrap().to_string();
24+
(temp_dir, file_path_str)
25+
}
26+
27+
/// Benchmark SI formatting with different number counts
28+
#[divan::bench(args = [1_000_000])]
29+
fn numfmt_to_si(bencher: Bencher, count: usize) {
30+
let (_temp_dir, file_path_str) = setup_benchmark(generate_numbers(count));
31+
32+
bencher.bench(|| {
33+
black_box(run_util_function(uumain, &["--to=si", &file_path_str]));
34+
});
35+
}
36+
37+
/// Benchmark SI formatting with precision format
38+
#[divan::bench(args = [1_000_000])]
39+
fn numfmt_to_si_precision(bencher: Bencher, count: usize) {
40+
let (_temp_dir, file_path_str) = setup_benchmark(generate_numbers(count));
41+
42+
bencher.bench(|| {
43+
black_box(run_util_function(
44+
uumain,
45+
&["--to=si", "--format=%.6f", &file_path_str],
46+
));
47+
});
48+
}
49+
50+
/// Benchmark IEC (binary) formatting
51+
#[divan::bench(args = [1_000_000])]
52+
fn numfmt_to_iec(bencher: Bencher, count: usize) {
53+
let (_temp_dir, file_path_str) = setup_benchmark(generate_numbers(count));
54+
55+
bencher.bench(|| {
56+
black_box(run_util_function(uumain, &["--to=iec", &file_path_str]));
57+
});
58+
}
59+
60+
/// Benchmark parsing from SI format back to raw numbers
61+
#[divan::bench(args = [1_000_000])]
62+
fn numfmt_from_si(bencher: Bencher, count: usize) {
63+
// Generate SI formatted data (e.g., "1.0K", "2.0K", etc.)
64+
let data = (1..=count)
65+
.map(|n| format!("{:.1}K", n as f64 / 1000.0))
66+
.collect::<Vec<_>>()
67+
.join("\n");
68+
let (_temp_dir, file_path_str) = setup_benchmark(data);
69+
70+
bencher.bench(|| {
71+
black_box(run_util_function(uumain, &["--from=si", &file_path_str]));
72+
});
73+
}
74+
75+
/// Benchmark large numbers with SI formatting
76+
#[divan::bench(args = [1_000_000])]
77+
fn numfmt_large_numbers_si(bencher: Bencher, count: usize) {
78+
// Generate larger numbers (millions to billions range)
79+
let data = (1..=count)
80+
.map(|n| (n * 1_000_000).to_string())
81+
.collect::<Vec<_>>()
82+
.join("\n");
83+
let (_temp_dir, file_path_str) = setup_benchmark(data);
84+
85+
bencher.bench(|| {
86+
black_box(run_util_function(uumain, &["--to=si", &file_path_str]));
87+
});
88+
}
89+
90+
/// Benchmark different padding widths
91+
#[divan::bench(args = [(1_000_000, 5), (1_000_000, 50)])]
92+
fn numfmt_padding(bencher: Bencher, (count, padding): (usize, usize)) {
93+
let (_temp_dir, file_path_str) = setup_benchmark(generate_numbers(count));
94+
let padding_arg = format!("--padding={padding}");
95+
96+
bencher.bench(|| {
97+
black_box(run_util_function(
98+
uumain,
99+
&["--to=si", &padding_arg, &file_path_str],
100+
));
101+
});
102+
}
103+
104+
/// Benchmark round modes with SI formatting
105+
#[divan::bench(args = [("up", 100_000), ("down", 1_000_000), ("towards-zero", 1_000_000)])]
106+
fn numfmt_round_modes(bencher: Bencher, (round_mode, count): (&str, usize)) {
107+
let (_temp_dir, file_path_str) = setup_benchmark(generate_numbers(count));
108+
let round_arg = format!("--round={round_mode}");
109+
110+
bencher.bench(|| {
111+
black_box(run_util_function(
112+
uumain,
113+
&["--to=si", &round_arg, &file_path_str],
114+
));
115+
});
116+
}
117+
118+
fn main() {
119+
divan::main();
120+
}

0 commit comments

Comments
 (0)