Skip to content

Commit 2f23eeb

Browse files
author
Gunter Schmidt
committed
Fix: benchmarks in Windows
Also some clippy findings
1 parent 46f0713 commit 2f23eeb

6 files changed

Lines changed: 543 additions & 527 deletions

File tree

src/uu/cmp/benches/cmp_bench.rs

Lines changed: 158 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -1,151 +1,158 @@
1-
#![allow(unused)]
2-
// This file is part of the uutils diffutils package.
3-
//
4-
// For the full copyright and license information, please view the LICENSE-*
5-
// files that was distributed with this source code.
6-
7-
//! Benches for all utils in diffutils.
8-
//!
9-
//! There is a file generator included to create files of different sizes for comparison. \
10-
//! Set the TEMP_DIR const to keep the files. df_to_ files have small changes in them, search for '#'. \
11-
//! File generation up to 1 GB is really fast, Benchmarking above 100 MB takes very long.
12-
13-
/// Generate test files with these sizes in KB.
14-
const FILE_SIZES_IN_KILO_BYTES: [u64; 4] = [100, 1 * MB, 10 * MB, 25 * MB];
15-
const NUM_DIFF: u64 = 4;
16-
// Empty String to use TempDir (files will be removed after test) or specify dir to keep generated files
17-
const TEMP_DIR: &str = "";
18-
// just for FILE_SIZE_KILO_BYTES
19-
const MB: u64 = 1_000;
20-
21-
use std::sync::OnceLock;
22-
23-
use divan::Bencher;
24-
use tempfile::TempDir;
25-
use uu_cmp::{params_cmp::Params, uu_app};
26-
// use uu_cmp::parse_params;
27-
// use uu_cmp::uumain;
28-
use uudiff::benchmark::{
29-
bench_binary,
30-
prepare_bench::{BenchContext, generate_test_files_bytes},
31-
str_to_args,
32-
};
33-
34-
// bench the time it takes to parse the command line arguments
35-
#[divan::bench]
36-
fn cmp_parser(bencher: Bencher) {
37-
let cmd = "cmd file_1.txt file_2.txt -bl -n10M --ignore-initial=100KiB:1MiB";
38-
let args = str_to_args(&cmd).into_iter().peekable();
39-
bencher.with_inputs(|| args.clone()).bench_values(
40-
// |params: std::iter::Peekable<std::vec::IntoIter<std::ffi::OsString>>| parse_params(params),
41-
|params: std::iter::Peekable<std::vec::IntoIter<std::ffi::OsString>>| {
42-
let matches = uudiff::clap_localization::handle_clap_result(uu_app(), params).unwrap();
43-
let params: Params = matches.try_into().unwrap();
44-
},
45-
);
46-
// );
47-
}
48-
49-
// // // test the impact on the benchmark if not converting the cmd to Vec<OsString> (doubles for parse)
50-
// #[divan::bench]
51-
// fn cmp_parser_no_prepare() {
52-
// let cmd = "cmd file_1.txt file_2.txt -bl n10M --ignore-initial=100KiB:1MiB";
53-
// let args = str_to_args(&cmd).into_iter().peekable();
54-
// let _ = parse_params(args);
55-
// }
56-
57-
// bench equal, full file read
58-
#[divan::bench(args = FILE_SIZES_IN_KILO_BYTES)]
59-
fn cmp_compare_files_equal(bencher: Bencher, kb: u64) {
60-
let fp = get_context().get_files_equal_kb(kb).unwrap();
61-
let cmd = format!("cmp {} {}", fp.from, fp.to);
62-
let args = str_to_args(&cmd).into_iter();
63-
64-
bencher
65-
// .with_inputs(|| prepare::cmp_params_identical_testfiles(lines))
66-
.with_inputs(|| args.clone())
67-
.bench_refs(|params| uu_cmp::uumain(params.peekable()));
68-
}
69-
70-
// bench different; cmp exits on first difference
71-
#[divan::bench(args = FILE_SIZES_IN_KILO_BYTES)]
72-
fn cmp_compare_files_different(bencher: Bencher, kb: u64) {
73-
let fp = get_context().get_files_different_kb(kb).unwrap();
74-
let cmd = format!("cmp -s {} {}", fp.from, fp.to);
75-
let args = str_to_args(&cmd).into_iter();
76-
77-
bencher
78-
// .with_inputs(|| prepare::cmp_params_identical_testfiles(lines))
79-
.with_inputs(|| args.clone())
80-
.bench_refs(|params| uu_cmp::uumain(params.peekable()));
81-
}
82-
83-
// TODO use coreutils bench logic
84-
// bench original GNU cmp
85-
#[cfg(feature = "feat_run_binary_bench")]
86-
#[divan::bench(args = FILE_SIZES_IN_KILO_BYTES)]
87-
fn cmd_cmp_gnu_equal(bencher: Bencher, kb: u64) {
88-
let fp = get_context().get_files_equal_kb(kb).unwrap();
89-
let args_str = format!("{} {}", fp.from, fp.to);
90-
bencher
91-
// .with_inputs(|| prepare::cmp_params_identical_testfiles(lines))
92-
.with_inputs(|| args_str.clone())
93-
.bench_refs(|cmd_args| bench_binary::bench_binary("cmp", cmd_args));
94-
}
95-
96-
// bench the compiled release version
97-
#[cfg(feature = "feat_run_binary_bench")]
98-
#[divan::bench(args = FILE_SIZES_IN_KILO_BYTES)]
99-
fn cmd_cmp_release_equal(bencher: Bencher, kb: u64) {
100-
// search for src, then shorten path
101-
let dir = std::env::current_dir().unwrap();
102-
let path = dir.to_string_lossy();
103-
let path = path.trim_end_matches("src/uu/cmp");
104-
let prg = path.to_string() + "target/release/cmp";
105-
106-
let fp = get_context().get_files_equal_kb(kb).unwrap();
107-
let args_str = format!("{} {}", fp.from, fp.to);
108-
109-
bencher
110-
// .with_inputs(|| prepare::cmp_params_identical_testfiles(lines))
111-
.with_inputs(|| args_str.clone())
112-
.bench_refs(|cmd_args| bench_binary::bench_binary(&prg, cmd_args));
113-
}
114-
115-
// Since each bench function is separate in Divan it is more difficult to dynamically create test data.
116-
// This keeps the TempDir alive until the program exits and generates the files only once.
117-
static SHARED_CONTEXT: OnceLock<BenchContext> = OnceLock::new();
118-
/// Creates the test files once and provides them to all tests.
119-
pub fn get_context() -> &'static BenchContext {
120-
SHARED_CONTEXT.get_or_init(|| {
121-
let mut ctx = BenchContext::default();
122-
if TEMP_DIR.is_empty() {
123-
let tmp_dir = TempDir::new().expect("Failed to create temp dir");
124-
ctx.tmp_dir = Some(tmp_dir);
125-
} else {
126-
// uses current directory, the generated files are kept
127-
let path = std::path::Path::new(TEMP_DIR);
128-
if !path.exists() {
129-
std::fs::create_dir_all(path).expect("Path {path} could not be created");
130-
}
131-
ctx.dir = TEMP_DIR.to_string();
132-
};
133-
134-
// generate test bytes
135-
for kb in FILE_SIZES_IN_KILO_BYTES {
136-
let f = generate_test_files_bytes(ctx.get_path(), kb * 1000, 0, "eq")
137-
.expect("generate_test_files failed");
138-
ctx.files_equal.push(f);
139-
let f = generate_test_files_bytes(ctx.get_path(), kb * 1000, NUM_DIFF, "df")
140-
.expect("generate_test_files failed");
141-
ctx.files_different.push(f);
142-
}
143-
144-
ctx
145-
})
146-
}
147-
148-
fn main() {
149-
// Run registered benchmarks.
150-
divan::main();
151-
}
1+
#![allow(unused)]
2+
// This file is part of the uutils diffutils package.
3+
//
4+
// For the full copyright and license information, please view the LICENSE-*
5+
// files that was distributed with this source code.
6+
7+
//! Benches for all utils in diffutils.
8+
//!
9+
//! There is a file generator included to create files of different sizes for comparison. \
10+
//! Set the TEMP_DIR const to keep the files. df_to_ files have small changes in them, search for '#'. \
11+
//! File generation up to 1 GB is really fast, Benchmarking above 100 MB takes very long.
12+
13+
/// Generate test files with these sizes in KB.
14+
const FILE_SIZES_IN_KILO_BYTES: [u64; 5] = [100, 1 * MB, 10 * MB, 25 * MB, 100 * MB];
15+
const NUM_DIFF: u64 = 4;
16+
// Empty String to use TempDir (files will be removed after test) or specify dir to keep generated files
17+
const TEMP_DIR: &str = "";
18+
// just for FILE_SIZE_KILO_BYTES
19+
const MB: u64 = 1_000;
20+
21+
use std::{
22+
path::{Path, PathBuf},
23+
sync::OnceLock,
24+
};
25+
26+
use divan::Bencher;
27+
use tempfile::TempDir;
28+
use uu_cmp::{params_cmp::Params, uu_app};
29+
use uudiff::benchmark::{
30+
bench_binary,
31+
prepare_bench::{BenchContext, generate_test_files_bytes},
32+
str_to_args,
33+
};
34+
35+
// bench the time it takes to parse the command line arguments
36+
#[divan::bench]
37+
fn cmp_parser(bencher: Bencher) {
38+
let cmd = "cmd file_1.txt file_2.txt -bl -n10M --ignore-initial=100KiB:1MiB";
39+
let args = str_to_args(&cmd).into_iter().peekable();
40+
bencher.with_inputs(|| args.clone()).bench_values(
41+
// |params: std::iter::Peekable<std::vec::IntoIter<std::ffi::OsString>>| parse_params(params),
42+
|params: std::iter::Peekable<std::vec::IntoIter<std::ffi::OsString>>| {
43+
let matches = uudiff::clap_localization::handle_clap_result(uu_app(), params).unwrap();
44+
let params: Params = matches.try_into().unwrap();
45+
},
46+
);
47+
// );
48+
}
49+
50+
// // // test the impact on the benchmark if not converting the cmd to Vec<OsString> (doubles for parse)
51+
// #[divan::bench]
52+
// fn cmp_parser_no_prepare() {
53+
// let cmd = "cmd file_1.txt file_2.txt -bl n10M --ignore-initial=100KiB:1MiB";
54+
// let args = str_to_args(&cmd).into_iter().peekable();
55+
// let _ = parse_params(args);
56+
// }
57+
58+
// bench equal, full file read
59+
#[divan::bench(args = FILE_SIZES_IN_KILO_BYTES)]
60+
fn cmp_compare_files_equal(bencher: Bencher, kb: u64) {
61+
let fp = get_context().get_files_equal_kb(kb).unwrap();
62+
let cmd = format!("cmp {} {}", fp.from, fp.to);
63+
let args = str_to_args(&cmd).into_iter();
64+
let matches =
65+
uudiff::clap_localization::handle_clap_result_with_exit_code(uu_app(), args, 2).unwrap();
66+
let params: Params = matches.try_into().unwrap();
67+
68+
bencher
69+
// .with_inputs(|| prepare::cmp_params_identical_testfiles(lines))
70+
.with_inputs(|| params.clone())
71+
.bench_refs(|params| uu_cmp::cmp_compare(params));
72+
}
73+
74+
// bench different; cmp exits on first difference
75+
#[divan::bench(args = FILE_SIZES_IN_KILO_BYTES)]
76+
fn cmp_compare_files_different(bencher: Bencher, kb: u64) {
77+
let fp = get_context().get_files_different_kb(kb).unwrap();
78+
let cmd = format!("cmp -s {} {}", fp.from, fp.to);
79+
let args = str_to_args(&cmd).into_iter();
80+
81+
bencher
82+
// .with_inputs(|| prepare::cmp_params_identical_testfiles(lines))
83+
.with_inputs(|| args.clone())
84+
.bench_refs(|params| uu_cmp::uumain(params.peekable()));
85+
}
86+
87+
// TODO use coreutils bench logic
88+
// bench original GNU cmp
89+
#[cfg(feature = "feat_run_binary_bench")]
90+
#[divan::bench(args = FILE_SIZES_IN_KILO_BYTES)]
91+
fn cmd_cmp_gnu_equal(bencher: Bencher, kb: u64) {
92+
let fp = get_context().get_files_equal_kb(kb).unwrap();
93+
let args_str = format!("{} {}", fp.from, fp.to);
94+
bencher
95+
// .with_inputs(|| prepare::cmp_params_identical_testfiles(lines))
96+
.with_inputs(|| args_str.clone())
97+
.bench_refs(|cmd_args| bench_binary::bench_binary(&PathBuf::from("cmp"), cmd_args));
98+
}
99+
100+
// bench the compiled release version
101+
#[cfg(feature = "feat_run_binary_bench")]
102+
#[divan::bench(args = FILE_SIZES_IN_KILO_BYTES)]
103+
fn cmd_cmp_release_equal(bencher: Bencher, kb: u64) {
104+
let mut dir = std::env::current_dir().unwrap();
105+
let suffix = Path::new("src").join("uu").join("cmp");
106+
if dir.ends_with(suffix) {
107+
dir.pop();
108+
dir.pop();
109+
dir.pop();
110+
}
111+
let prg = dir.join("target").join("release").join("cmp");
112+
113+
let fp = get_context().get_files_equal_kb(kb).unwrap();
114+
let args_str = format!("{} {}", fp.from, fp.to);
115+
116+
bencher
117+
// .with_inputs(|| prepare::cmp_params_identical_testfiles(lines))
118+
.with_inputs(|| args_str.clone())
119+
.bench_refs(|cmd_args| bench_binary::bench_binary(&prg, cmd_args));
120+
}
121+
122+
// Since each bench function is separate in Divan it is more difficult to dynamically create test data.
123+
// This keeps the TempDir alive until the program exits and generates the files only once.
124+
static SHARED_CONTEXT: OnceLock<BenchContext> = OnceLock::new();
125+
/// Creates the test files once and provides them to all tests.
126+
pub fn get_context() -> &'static BenchContext {
127+
SHARED_CONTEXT.get_or_init(|| {
128+
let mut ctx = BenchContext::default();
129+
if TEMP_DIR.is_empty() {
130+
let tmp_dir = TempDir::new().expect("Failed to create temp dir");
131+
ctx.tmp_dir = Some(tmp_dir);
132+
} else {
133+
// uses current directory, the generated files are kept
134+
let path = std::path::Path::new(TEMP_DIR);
135+
if !path.exists() {
136+
std::fs::create_dir_all(path).expect("Path {path} could not be created");
137+
}
138+
ctx.dir = TEMP_DIR.to_string();
139+
};
140+
141+
// generate test bytes
142+
for kb in FILE_SIZES_IN_KILO_BYTES {
143+
let f = generate_test_files_bytes(ctx.get_path(), kb * 1000, 0, "eq")
144+
.expect("generate_test_files failed");
145+
ctx.files_equal.push(f);
146+
let f = generate_test_files_bytes(ctx.get_path(), kb * 1000, NUM_DIFF, "df")
147+
.expect("generate_test_files failed");
148+
ctx.files_different.push(f);
149+
}
150+
151+
ctx
152+
})
153+
}
154+
155+
fn main() {
156+
// Run registered benchmarks.
157+
divan::main();
158+
}

0 commit comments

Comments
 (0)