Skip to content

Commit fd68328

Browse files
authored
Merge pull request #9928 from sylvestre/bench
benchmark: some minor improvements
2 parents 1ec809c + 4f5e665 commit fd68328

File tree

3 files changed

+91
-74
lines changed

3 files changed

+91
-74
lines changed

src/uu/cp/benches/cp_bench.rs

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,11 @@
44
// file that was distributed with this source code.
55

66
use divan::{Bencher, black_box};
7-
use std::fs::{self, File};
8-
use std::io::Write;
7+
use std::fs;
98
use std::path::Path;
109
use tempfile::TempDir;
1110
use uu_cp::uumain;
12-
use uucore::benchmark::{fs_tree, run_util_function};
13-
14-
fn remove_path(path: &Path) {
15-
if !path.exists() {
16-
return;
17-
}
18-
19-
if path.is_dir() {
20-
fs::remove_dir_all(path).unwrap();
21-
} else {
22-
fs::remove_file(path).unwrap();
23-
}
24-
}
11+
use uucore::benchmark::{binary_data, fs_tree, fs_utils, run_util_function};
2512

2613
fn bench_cp_directory<F>(bencher: Bencher, args: &[&str], setup_source: F)
2714
where
@@ -38,7 +25,7 @@ where
3825
let dest_str = dest.to_str().unwrap();
3926

4027
bencher.bench(|| {
41-
remove_path(&dest);
28+
fs_utils::remove_path(&dest);
4229

4330
let mut full_args = Vec::with_capacity(args.len() + 2);
4431
full_args.extend_from_slice(args);
@@ -99,16 +86,13 @@ fn cp_large_file(bencher: Bencher, size_mb: usize) {
9986
let source = temp_dir.path().join("source.bin");
10087
let dest = temp_dir.path().join("dest.bin");
10188

102-
let buffer = vec![b'x'; size_mb * 1024 * 1024];
103-
let mut file = File::create(&source).unwrap();
104-
file.write_all(&buffer).unwrap();
105-
file.sync_all().unwrap();
89+
binary_data::create_file(&source, size_mb, b'x');
10690

10791
let source_str = source.to_str().unwrap();
10892
let dest_str = dest.to_str().unwrap();
10993

11094
bencher.bench(|| {
111-
remove_path(&dest);
95+
fs_utils::remove_path(&dest);
11296

11397
black_box(run_util_function(uumain, &[source_str, dest_str]));
11498
});

src/uu/dd/benches/dd_bench.rs

Lines changed: 46 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,25 @@
44
// file that was distributed with this source code.
55

66
use divan::{Bencher, black_box};
7-
use std::fs::{self, File};
8-
use std::io::Write;
9-
use std::path::Path;
107
use tempfile::TempDir;
118
use uu_dd::uumain;
12-
use uucore::benchmark::run_util_function;
13-
14-
fn create_test_file(path: &Path, size_mb: usize) {
15-
let buffer = vec![b'x'; size_mb * 1024 * 1024];
16-
let mut file = File::create(path).unwrap();
17-
file.write_all(&buffer).unwrap();
18-
file.sync_all().unwrap();
19-
}
20-
21-
fn remove_file(path: &Path) {
22-
if path.exists() {
23-
fs::remove_file(path).unwrap();
24-
}
25-
}
9+
use uucore::benchmark::{binary_data, fs_utils, run_util_function};
2610

2711
/// Benchmark basic dd copy with default settings
28-
#[divan::bench(args = [32])]
29-
fn dd_copy_default(bencher: Bencher, size_mb: usize) {
12+
#[divan::bench]
13+
fn dd_copy_default(bencher: Bencher) {
14+
let size_mb = 32;
3015
let temp_dir = TempDir::new().unwrap();
3116
let input = temp_dir.path().join("input.bin");
3217
let output = temp_dir.path().join("output.bin");
3318

34-
create_test_file(&input, size_mb);
19+
binary_data::create_file(&input, size_mb, b'x');
3520

3621
let input_str = input.to_str().unwrap();
3722
let output_str = output.to_str().unwrap();
3823

3924
bencher.bench(|| {
40-
remove_file(&output);
25+
fs_utils::remove_path(&output);
4126
black_box(run_util_function(
4227
uumain,
4328
&[
@@ -50,19 +35,20 @@ fn dd_copy_default(bencher: Bencher, size_mb: usize) {
5035
}
5136

5237
/// Benchmark dd copy with 4KB block size (common page size)
53-
#[divan::bench(args = [24])]
54-
fn dd_copy_4k_blocks(bencher: Bencher, size_mb: usize) {
38+
#[divan::bench]
39+
fn dd_copy_4k_blocks(bencher: Bencher) {
40+
let size_mb = 24;
5541
let temp_dir = TempDir::new().unwrap();
5642
let input = temp_dir.path().join("input.bin");
5743
let output = temp_dir.path().join("output.bin");
5844

59-
create_test_file(&input, size_mb);
45+
binary_data::create_file(&input, size_mb, b'x');
6046

6147
let input_str = input.to_str().unwrap();
6248
let output_str = output.to_str().unwrap();
6349

6450
bencher.bench(|| {
65-
remove_file(&output);
51+
fs_utils::remove_path(&output);
6652
black_box(run_util_function(
6753
uumain,
6854
&[
@@ -76,19 +62,20 @@ fn dd_copy_4k_blocks(bencher: Bencher, size_mb: usize) {
7662
}
7763

7864
/// Benchmark dd copy with 64KB block size
79-
#[divan::bench(args = [64])]
80-
fn dd_copy_64k_blocks(bencher: Bencher, size_mb: usize) {
65+
#[divan::bench]
66+
fn dd_copy_64k_blocks(bencher: Bencher) {
67+
let size_mb = 64;
8168
let temp_dir = TempDir::new().unwrap();
8269
let input = temp_dir.path().join("input.bin");
8370
let output = temp_dir.path().join("output.bin");
8471

85-
create_test_file(&input, size_mb);
72+
binary_data::create_file(&input, size_mb, b'x');
8673

8774
let input_str = input.to_str().unwrap();
8875
let output_str = output.to_str().unwrap();
8976

9077
bencher.bench(|| {
91-
remove_file(&output);
78+
fs_utils::remove_path(&output);
9279
black_box(run_util_function(
9380
uumain,
9481
&[
@@ -102,19 +89,20 @@ fn dd_copy_64k_blocks(bencher: Bencher, size_mb: usize) {
10289
}
10390

10491
/// Benchmark dd copy with 1MB block size
105-
#[divan::bench(args = [128])]
106-
fn dd_copy_1m_blocks(bencher: Bencher, size_mb: usize) {
92+
#[divan::bench]
93+
fn dd_copy_1m_blocks(bencher: Bencher) {
94+
let size_mb = 128;
10795
let temp_dir = TempDir::new().unwrap();
10896
let input = temp_dir.path().join("input.bin");
10997
let output = temp_dir.path().join("output.bin");
11098

111-
create_test_file(&input, size_mb);
99+
binary_data::create_file(&input, size_mb, b'x');
112100

113101
let input_str = input.to_str().unwrap();
114102
let output_str = output.to_str().unwrap();
115103

116104
bencher.bench(|| {
117-
remove_file(&output);
105+
fs_utils::remove_path(&output);
118106
black_box(run_util_function(
119107
uumain,
120108
&[
@@ -128,19 +116,20 @@ fn dd_copy_1m_blocks(bencher: Bencher, size_mb: usize) {
128116
}
129117

130118
/// Benchmark dd copy with separate input and output block sizes
131-
#[divan::bench(args = [48])]
132-
fn dd_copy_separate_blocks(bencher: Bencher, size_mb: usize) {
119+
#[divan::bench]
120+
fn dd_copy_separate_blocks(bencher: Bencher) {
121+
let size_mb = 48;
133122
let temp_dir = TempDir::new().unwrap();
134123
let input = temp_dir.path().join("input.bin");
135124
let output = temp_dir.path().join("output.bin");
136125

137-
create_test_file(&input, size_mb);
126+
binary_data::create_file(&input, size_mb, b'x');
138127

139128
let input_str = input.to_str().unwrap();
140129
let output_str = output.to_str().unwrap();
141130

142131
bencher.bench(|| {
143-
remove_file(&output);
132+
fs_utils::remove_path(&output);
144133
black_box(run_util_function(
145134
uumain,
146135
&[
@@ -155,19 +144,20 @@ fn dd_copy_separate_blocks(bencher: Bencher, size_mb: usize) {
155144
}
156145

157146
/// Benchmark dd with count limit (partial copy)
158-
#[divan::bench(args = [32])]
159-
fn dd_copy_partial(bencher: Bencher, size_mb: usize) {
147+
#[divan::bench]
148+
fn dd_copy_partial(bencher: Bencher) {
149+
let size_mb = 32;
160150
let temp_dir = TempDir::new().unwrap();
161151
let input = temp_dir.path().join("input.bin");
162152
let output = temp_dir.path().join("output.bin");
163153

164-
create_test_file(&input, size_mb);
154+
binary_data::create_file(&input, size_mb, b'x');
165155

166156
let input_str = input.to_str().unwrap();
167157
let output_str = output.to_str().unwrap();
168158

169159
bencher.bench(|| {
170-
remove_file(&output);
160+
fs_utils::remove_path(&output);
171161
black_box(run_util_function(
172162
uumain,
173163
&[
@@ -182,19 +172,20 @@ fn dd_copy_partial(bencher: Bencher, size_mb: usize) {
182172
}
183173

184174
/// Benchmark dd with skip (seeking in input)
185-
#[divan::bench(args = [48])]
186-
fn dd_copy_with_skip(bencher: Bencher, size_mb: usize) {
175+
#[divan::bench]
176+
fn dd_copy_with_skip(bencher: Bencher) {
177+
let size_mb = 48;
187178
let temp_dir = TempDir::new().unwrap();
188179
let input = temp_dir.path().join("input.bin");
189180
let output = temp_dir.path().join("output.bin");
190181

191-
create_test_file(&input, size_mb);
182+
binary_data::create_file(&input, size_mb, b'x');
192183

193184
let input_str = input.to_str().unwrap();
194185
let output_str = output.to_str().unwrap();
195186

196187
bencher.bench(|| {
197-
remove_file(&output);
188+
fs_utils::remove_path(&output);
198189
black_box(run_util_function(
199190
uumain,
200191
&[
@@ -209,19 +200,20 @@ fn dd_copy_with_skip(bencher: Bencher, size_mb: usize) {
209200
}
210201

211202
/// Benchmark dd with seek (seeking in output)
212-
#[divan::bench(args = [48])]
213-
fn dd_copy_with_seek(bencher: Bencher, size_mb: usize) {
203+
#[divan::bench]
204+
fn dd_copy_with_seek(bencher: Bencher) {
205+
let size_mb = 48;
214206
let temp_dir = TempDir::new().unwrap();
215207
let input = temp_dir.path().join("input.bin");
216208
let output = temp_dir.path().join("output.bin");
217209

218-
create_test_file(&input, size_mb);
210+
binary_data::create_file(&input, size_mb, b'x');
219211

220212
let input_str = input.to_str().unwrap();
221213
let output_str = output.to_str().unwrap();
222214

223215
bencher.bench(|| {
224-
remove_file(&output);
216+
fs_utils::remove_path(&output);
225217
black_box(run_util_function(
226218
uumain,
227219
&[
@@ -236,19 +228,20 @@ fn dd_copy_with_seek(bencher: Bencher, size_mb: usize) {
236228
}
237229

238230
/// Benchmark dd with different block sizes for comparison
239-
#[divan::bench(args = [32])]
240-
fn dd_copy_8k_blocks(bencher: Bencher, size_mb: usize) {
231+
#[divan::bench]
232+
fn dd_copy_8k_blocks(bencher: Bencher) {
233+
let size_mb = 32;
241234
let temp_dir = TempDir::new().unwrap();
242235
let input = temp_dir.path().join("input.bin");
243236
let output = temp_dir.path().join("output.bin");
244237

245-
create_test_file(&input, size_mb);
238+
binary_data::create_file(&input, size_mb, b'x');
246239

247240
let input_str = input.to_str().unwrap();
248241
let output_str = output.to_str().unwrap();
249242

250243
bencher.bench(|| {
251-
remove_file(&output);
244+
fs_utils::remove_path(&output);
252245
black_box(run_util_function(
253246
uumain,
254247
&[

src/uucore/src/lib/features/benchmark.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,46 @@ pub mod text_data {
289289
}
290290
}
291291

292+
/// Binary data generation utilities for benchmarking
293+
pub mod binary_data {
294+
use std::fs::File;
295+
use std::io::Write;
296+
use std::path::Path;
297+
298+
/// Create a binary file filled with a repeated pattern
299+
///
300+
/// Creates a file of the specified size (in MB) filled with the given byte pattern.
301+
/// This is useful for benchmarking utilities that work with large binary files like dd, cp, etc.
302+
pub fn create_file(path: &Path, size_mb: usize, pattern: u8) {
303+
let buffer = vec![pattern; size_mb * 1024 * 1024];
304+
let mut file = File::create(path).unwrap();
305+
file.write_all(&buffer).unwrap();
306+
file.sync_all().unwrap();
307+
}
308+
}
309+
310+
/// Filesystem utilities for benchmarking
311+
pub mod fs_utils {
312+
use std::fs;
313+
use std::path::Path;
314+
315+
/// Remove a file or directory if it exists
316+
///
317+
/// This is a convenience function for cleaning up between benchmark iterations.
318+
/// It handles both files and directories, and is a no-op if the path doesn't exist.
319+
pub fn remove_path(path: &Path) {
320+
if !path.exists() {
321+
return;
322+
}
323+
324+
if path.is_dir() {
325+
fs::remove_dir_all(path).unwrap();
326+
} else {
327+
fs::remove_file(path).unwrap();
328+
}
329+
}
330+
}
331+
292332
/// Filesystem tree generation utilities for benchmarking
293333
pub mod fs_tree {
294334
use std::fs::{self, File};

0 commit comments

Comments
 (0)