Skip to content

Commit 1532d65

Browse files
committed
numfmt: add benchmark
1 parent 54f32bd commit 1532d65

File tree

3 files changed

+132
-0
lines changed

3 files changed

+132
-0
lines changed

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

0 commit comments

Comments
 (0)