|
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 divan::Bencher; |
22 | | -use std::{path::Path, sync::OnceLock}; |
23 | | -use tempfile::TempDir; |
24 | | -use uudiff::benchmark::{ |
25 | | - // bench_binary, |
26 | | - prepare_bench::{BenchContext, generate_test_files_bytes}, |
27 | | - str_to_args, |
28 | | -}; |
29 | | - |
30 | | -// bench the time it takes to parse the command line arguments |
31 | | -#[divan::bench] |
32 | | -fn diff_parser_old(bencher: Bencher) { |
33 | | - let cmd = "diff file_1.txt file_2.txt -s --brief --expand-tabs --width=100"; |
34 | | - let args = str_to_args(&cmd).into_iter().peekable(); |
35 | | - bencher |
36 | | - .with_inputs(|| args.clone()) |
37 | | - .bench_values(|data| uu_diff::params_old::parse_params(data)); |
38 | | -} |
39 | | - |
40 | | -// bench the time it takes to parse the command line arguments |
41 | | -#[divan::bench(sample_size = 100)] |
42 | | -fn diff_parser_clap(bencher: Bencher) { |
43 | | - let cmd = "diff file_1.txt file_2.txt -s --brief --expand-tabs --width=100"; |
44 | | - let args_prep = str_to_args(&cmd).into_iter().peekable(); |
45 | | - bencher |
46 | | - .with_inputs(|| args_prep.clone()) |
47 | | - .bench_values(|args| { |
48 | | - let args = uu_diff::clap_preparation(args); |
49 | | - let matches = uudiff::clap_localization::handle_clap_result_with_exit_code( |
50 | | - uu_diff::uu_app(), |
51 | | - args, |
52 | | - 2, |
53 | | - ) |
54 | | - .unwrap(); |
55 | | - let _params: uu_diff::params_diff::Params = matches.try_into().unwrap(); |
56 | | - }); |
57 | | -} |
58 | | - |
59 | | -// bench the actual compare |
60 | | -// bench equal, full file read |
61 | | -#[divan::bench(args = FILE_SIZES_IN_KILO_BYTES)] |
62 | | -fn diff_compare_files_equal(bencher: Bencher, kb: u64) { |
63 | | - let fp = get_context().get_files_equal_kb(kb).unwrap(); |
64 | | - let cmd = format!("diff {} {}", fp.from, fp.to); |
65 | | - let args = str_to_args(&cmd).into_iter(); |
66 | | - |
67 | | - bencher |
68 | | - // .with_inputs(|| prepare::diff_params_identical_testfiles(lines)) |
69 | | - .with_inputs(|| args.clone()) |
70 | | - .bench_refs(|params| uu_diff::uumain(params.peekable())); |
71 | | -} |
72 | | - |
73 | | -// bench original GNU diff |
74 | | -#[cfg(feature = "feat_run_binary_bench")] |
75 | | -#[divan::bench(args = FILE_SIZES_IN_KILO_BYTES)] |
76 | | -fn cmd_diff_gnu_equal(bencher: Bencher, kb: u64) { |
77 | | - let fp = get_context().get_files_equal_kb(kb).unwrap(); |
78 | | - let args_str = format!("{} {}", fp.from, fp.to); |
79 | | - bencher |
80 | | - // .with_inputs(|| prepare::cmp_params_identical_testfiles(lines)) |
81 | | - .with_inputs(|| args_str.clone()) |
82 | | - .bench_refs(|cmd_args| uudiff::benchmark::bench_binary::bench_binary("diff", cmd_args)); |
83 | | -} |
84 | | - |
85 | | -// bench the compiled release version |
86 | | -#[cfg(feature = "feat_run_binary_bench")] |
87 | | -#[divan::bench(args = FILE_SIZES_IN_KILO_BYTES)] |
88 | | -fn cmd_diff_release_equal(bencher: Bencher, kb: u64) { |
89 | | - // search for src, then shorten path |
90 | | - let dir = std::env::current_dir().unwrap(); |
91 | | - let path = dir.to_string_lossy(); |
92 | | - let path = path.trim_end_matches("src/uu/diff"); |
93 | | - let prg = path.to_string() + "target/release/diff"; |
94 | | - |
95 | | - let fp = get_context().get_files_equal_kb(kb).unwrap(); |
96 | | - let args_str = format!("{} {}", fp.from, fp.to); |
97 | | - |
98 | | - bencher |
99 | | - // .with_inputs(|| prepare::cmp_params_identical_testfiles(lines)) |
100 | | - .with_inputs(|| args_str.clone()) |
101 | | - .bench_refs(|cmd_args| uudiff::benchmark::bench_binary::bench_binary(&prg, cmd_args)); |
102 | | -} |
103 | | - |
104 | | -// Since each bench function is separate in Divan it is more difficult to dynamically create test data. |
105 | | -// This keeps the TempDir alive until the program exits and generates the files only once. |
106 | | -static SHARED_CONTEXT: OnceLock<BenchContext> = OnceLock::new(); |
107 | | -/// Creates the test files once and provides them to all tests. |
108 | | -pub fn get_context() -> &'static BenchContext { |
109 | | - SHARED_CONTEXT.get_or_init(|| { |
110 | | - let mut ctx = BenchContext::default(); |
111 | | - if TEMP_DIR.is_empty() { |
112 | | - let tmp_dir = TempDir::new().expect("Failed to create temp dir"); |
113 | | - ctx.tmp_dir = Some(tmp_dir); |
114 | | - } else { |
115 | | - // uses current directory, the generated files are kept |
116 | | - let path = Path::new(TEMP_DIR); |
117 | | - if !path.exists() { |
118 | | - std::fs::create_dir_all(path).expect("Path {path} could not be created"); |
119 | | - } |
120 | | - ctx.dir = TEMP_DIR.to_string(); |
121 | | - }; |
122 | | - |
123 | | - // generate test bytes |
124 | | - for kb in FILE_SIZES_IN_KILO_BYTES { |
125 | | - let f = generate_test_files_bytes(ctx.get_path(), kb * 1000, 0, "eq") |
126 | | - .expect("generate_test_files failed"); |
127 | | - ctx.files_equal.push(f); |
128 | | - let f = generate_test_files_bytes(ctx.get_path(), kb * 1000, NUM_DIFF, "df") |
129 | | - .expect("generate_test_files failed"); |
130 | | - ctx.files_different.push(f); |
131 | | - } |
132 | | - |
133 | | - ctx |
134 | | - }) |
135 | | -} |
136 | | - |
137 | | -fn main() { |
138 | | - // Run registered benchmarks. |
139 | | - divan::main(); |
140 | | -} |
| 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 divan::Bencher; |
| 22 | +use std::{ |
| 23 | + path::{Path, PathBuf}, |
| 24 | + sync::OnceLock, |
| 25 | +}; |
| 26 | +use tempfile::TempDir; |
| 27 | +use uudiff::benchmark::{ |
| 28 | + // bench_binary, |
| 29 | + prepare_bench::{BenchContext, generate_test_files_bytes}, |
| 30 | + str_to_args, |
| 31 | +}; |
| 32 | + |
| 33 | +// bench the time it takes to parse the command line arguments |
| 34 | +#[divan::bench] |
| 35 | +fn diff_parser_old(bencher: Bencher) { |
| 36 | + let cmd = "diff file_1.txt file_2.txt -s --brief --expand-tabs --width=100"; |
| 37 | + let args = str_to_args(&cmd).into_iter().peekable(); |
| 38 | + bencher |
| 39 | + .with_inputs(|| args.clone()) |
| 40 | + .bench_values(|data| uu_diff::params_old::parse_params(data)); |
| 41 | +} |
| 42 | + |
| 43 | +// bench the time it takes to parse the command line arguments |
| 44 | +#[divan::bench(sample_size = 100)] |
| 45 | +fn diff_parser_clap(bencher: Bencher) { |
| 46 | + let cmd = "diff file_1.txt file_2.txt -s --brief --expand-tabs --width=100"; |
| 47 | + let args_prep = str_to_args(&cmd).into_iter().peekable(); |
| 48 | + bencher |
| 49 | + .with_inputs(|| args_prep.clone()) |
| 50 | + .bench_values(|args| { |
| 51 | + let args = uu_diff::clap_preparation(args); |
| 52 | + let matches = uudiff::clap_localization::handle_clap_result_with_exit_code( |
| 53 | + uu_diff::uu_app(), |
| 54 | + args, |
| 55 | + 2, |
| 56 | + ) |
| 57 | + .unwrap(); |
| 58 | + let _params: uu_diff::params_diff::Params = matches.try_into().unwrap(); |
| 59 | + }); |
| 60 | +} |
| 61 | + |
| 62 | +// bench the actual compare |
| 63 | +// bench equal, full file read |
| 64 | +#[divan::bench(args = FILE_SIZES_IN_KILO_BYTES)] |
| 65 | +fn diff_compare_files_equal(bencher: Bencher, kb: u64) { |
| 66 | + let fp = get_context().get_files_equal_kb(kb).unwrap(); |
| 67 | + let cmd = format!("diff {} {}", fp.from, fp.to); |
| 68 | + let args = str_to_args(&cmd).into_iter(); |
| 69 | + |
| 70 | + bencher |
| 71 | + // .with_inputs(|| prepare::diff_params_identical_testfiles(lines)) |
| 72 | + .with_inputs(|| args.clone()) |
| 73 | + .bench_refs(|params| uu_diff::uumain(params.peekable())); |
| 74 | +} |
| 75 | + |
| 76 | +// bench original GNU diff |
| 77 | +#[cfg(feature = "feat_run_binary_bench")] |
| 78 | +#[divan::bench(args = FILE_SIZES_IN_KILO_BYTES)] |
| 79 | +fn cmd_diff_gnu_equal(bencher: Bencher, kb: u64) { |
| 80 | + let fp = get_context().get_files_equal_kb(kb).unwrap(); |
| 81 | + let args_str = format!("{} {}", fp.from, fp.to); |
| 82 | + bencher |
| 83 | + // .with_inputs(|| prepare::cmp_params_identical_testfiles(lines)) |
| 84 | + .with_inputs(|| args_str.clone()) |
| 85 | + .bench_refs(|cmd_args| { |
| 86 | + uudiff::benchmark::bench_binary::bench_binary(&PathBuf::from("diff"), cmd_args) |
| 87 | + }); |
| 88 | +} |
| 89 | + |
| 90 | +// bench the compiled release version |
| 91 | +#[cfg(feature = "feat_run_binary_bench")] |
| 92 | +#[divan::bench(args = FILE_SIZES_IN_KILO_BYTES)] |
| 93 | +fn cmd_diff_release_equal(bencher: Bencher, kb: u64) { |
| 94 | + let mut dir = std::env::current_dir().unwrap(); |
| 95 | + let suffix = Path::new("src").join("uu").join("diff"); |
| 96 | + if dir.ends_with(suffix) { |
| 97 | + dir.pop(); |
| 98 | + dir.pop(); |
| 99 | + dir.pop(); |
| 100 | + } |
| 101 | + let prg = dir.join("target").join("release").join("diff"); |
| 102 | + |
| 103 | + let fp = get_context().get_files_equal_kb(kb).unwrap(); |
| 104 | + let args_str = format!("{} {}", fp.from, fp.to); |
| 105 | + |
| 106 | + bencher |
| 107 | + // .with_inputs(|| prepare::cmp_params_identical_testfiles(lines)) |
| 108 | + .with_inputs(|| args_str.clone()) |
| 109 | + .bench_refs(|cmd_args| uudiff::benchmark::bench_binary::bench_binary(&prg, cmd_args)); |
| 110 | +} |
| 111 | + |
| 112 | +// Since each bench function is separate in Divan it is more difficult to dynamically create test data. |
| 113 | +// This keeps the TempDir alive until the program exits and generates the files only once. |
| 114 | +static SHARED_CONTEXT: OnceLock<BenchContext> = OnceLock::new(); |
| 115 | +/// Creates the test files once and provides them to all tests. |
| 116 | +pub fn get_context() -> &'static BenchContext { |
| 117 | + SHARED_CONTEXT.get_or_init(|| { |
| 118 | + let mut ctx = BenchContext::default(); |
| 119 | + if TEMP_DIR.is_empty() { |
| 120 | + let tmp_dir = TempDir::new().expect("Failed to create temp dir"); |
| 121 | + ctx.tmp_dir = Some(tmp_dir); |
| 122 | + } else { |
| 123 | + // uses current directory, the generated files are kept |
| 124 | + let path = Path::new(TEMP_DIR); |
| 125 | + if !path.exists() { |
| 126 | + std::fs::create_dir_all(path).expect("Path {path} could not be created"); |
| 127 | + } |
| 128 | + ctx.dir = TEMP_DIR.to_string(); |
| 129 | + }; |
| 130 | + |
| 131 | + // generate test bytes |
| 132 | + for kb in FILE_SIZES_IN_KILO_BYTES { |
| 133 | + let f = generate_test_files_bytes(ctx.get_path(), kb * 1000, 0, "eq") |
| 134 | + .expect("generate_test_files failed"); |
| 135 | + ctx.files_equal.push(f); |
| 136 | + let f = generate_test_files_bytes(ctx.get_path(), kb * 1000, NUM_DIFF, "df") |
| 137 | + .expect("generate_test_files failed"); |
| 138 | + ctx.files_different.push(f); |
| 139 | + } |
| 140 | + |
| 141 | + ctx |
| 142 | + }) |
| 143 | +} |
| 144 | + |
| 145 | +fn main() { |
| 146 | + // Run registered benchmarks. |
| 147 | + divan::main(); |
| 148 | +} |
0 commit comments