|
13 | 13 | //! Both fds are restored after each iteration. |
14 | 14 |
|
15 | 15 | #[cfg(unix)] |
16 | | -use divan::{Bencher, black_box}; |
17 | | -#[cfg(unix)] |
18 | | -use uu_tr::uumain; |
19 | | -#[cfg(unix)] |
20 | | -use uucore::benchmark::{run_util_function, setup_test_file, text_data}; |
| 16 | +mod benches { |
| 17 | + use divan::{Bencher, black_box}; |
| 18 | + use uu_tr::uumain; |
| 19 | + use uucore::benchmark::{run_util_function, setup_test_file, text_data}; |
21 | 20 |
|
22 | | -#[cfg(unix)] |
23 | | -fn bench_tr_with_stdin(bencher: Bencher, data: &[u8], args: &[&str]) { |
24 | | - let file_path = setup_test_file(data); |
25 | | - let file = std::fs::File::open(file_path).unwrap(); |
26 | | - let devnull = std::fs::OpenOptions::new() |
27 | | - .write(true) |
28 | | - .open("/dev/null") |
29 | | - .unwrap(); |
30 | | - let stdin_bak = rustix::io::dup(rustix::stdio::stdin()).unwrap(); |
31 | | - let stdout_bak = rustix::io::dup(rustix::stdio::stdout()).unwrap(); |
| 21 | + fn bench_tr_with_stdin(bencher: Bencher, data: &[u8], args: &[&str]) { |
| 22 | + let file_path = setup_test_file(data); |
| 23 | + let file = std::fs::File::open(file_path).unwrap(); |
| 24 | + let devnull = std::fs::OpenOptions::new() |
| 25 | + .write(true) |
| 26 | + .open("/dev/null") |
| 27 | + .unwrap(); |
| 28 | + let stdin_bak = rustix::io::dup(rustix::stdio::stdin()).unwrap(); |
| 29 | + let stdout_bak = rustix::io::dup(rustix::stdio::stdout()).unwrap(); |
32 | 30 |
|
33 | | - bencher.bench_local(|| { |
34 | | - use rustix::stdio::{dup2_stdin, dup2_stdout}; |
35 | | - rustix::fs::seek(&file, rustix::fs::SeekFrom::Start(0)).unwrap(); |
36 | | - dup2_stdin(&file).unwrap(); |
37 | | - dup2_stdout(&devnull).unwrap(); |
38 | | - black_box(run_util_function(uumain, args)); |
39 | | - dup2_stdin(&stdin_bak).unwrap(); |
40 | | - dup2_stdout(&stdout_bak).unwrap(); |
41 | | - }); |
42 | | -} |
| 31 | + bencher.bench_local(|| { |
| 32 | + use rustix::stdio::{dup2_stdin, dup2_stdout}; |
| 33 | + rustix::fs::seek(&file, rustix::fs::SeekFrom::Start(0)).unwrap(); |
| 34 | + dup2_stdin(&file).unwrap(); |
| 35 | + dup2_stdout(&devnull).unwrap(); |
| 36 | + black_box(run_util_function(uumain, args)); |
| 37 | + dup2_stdin(&stdin_bak).unwrap(); |
| 38 | + dup2_stdout(&stdout_bak).unwrap(); |
| 39 | + }); |
| 40 | + } |
43 | 41 |
|
44 | | -#[cfg(unix)] |
45 | | -const SIZE_MB: usize = 16; |
| 42 | + const SIZE_MB: usize = 16; |
46 | 43 |
|
47 | | -/// ASCII lowercase->uppercase range translation. |
48 | | -/// Exercises the AVX2 ASCII-range fast path on x86_64 hosts that |
49 | | -/// support it, and the scalar range fallback on other targets. |
50 | | -#[cfg(unix)] |
51 | | -#[divan::bench] |
52 | | -fn tr_ascii_range_lower_to_upper(bencher: Bencher) { |
53 | | - let data = text_data::generate_by_size(SIZE_MB, 80); |
54 | | - bench_tr_with_stdin(bencher, &data, &["a-z", "A-Z"]); |
55 | | -} |
| 44 | + /// ASCII lowercase->uppercase range translation. |
| 45 | + /// Exercises the AVX2 ASCII-range fast path on x86_64 hosts that |
| 46 | + /// support it, and the scalar range fallback on other targets. |
| 47 | + #[divan::bench] |
| 48 | + fn tr_ascii_range_lower_to_upper(bencher: Bencher) { |
| 49 | + let data = text_data::generate_by_size(SIZE_MB, 80); |
| 50 | + bench_tr_with_stdin(bencher, &data, &["a-z", "A-Z"]); |
| 51 | + } |
56 | 52 |
|
57 | | -/// Single-character replacement. Exercises the existing |
58 | | -/// `process_single_char_replace` SIMD path; guards against |
59 | | -/// regressions outside the new range fast path. |
60 | | -#[cfg(unix)] |
61 | | -#[divan::bench] |
62 | | -fn tr_single_char_replace(bencher: Bencher) { |
63 | | - let data = text_data::generate_by_size(SIZE_MB, 80); |
64 | | - bench_tr_with_stdin(bencher, &data, &["a", "b"]); |
65 | | -} |
| 53 | + /// Single-character replacement. Exercises the existing |
| 54 | + /// `process_single_char_replace` SIMD path; guards against |
| 55 | + /// regressions outside the new range fast path. |
| 56 | + #[divan::bench] |
| 57 | + fn tr_single_char_replace(bencher: Bencher) { |
| 58 | + let data = text_data::generate_by_size(SIZE_MB, 80); |
| 59 | + bench_tr_with_stdin(bencher, &data, &["a", "b"]); |
| 60 | + } |
66 | 61 |
|
67 | | -/// Multi-character set translation. Falls through to the |
68 | | -/// 256-byte translation table path (no fast path applies). |
69 | | -#[cfg(unix)] |
70 | | -#[divan::bench] |
71 | | -fn tr_multi_char_translate(bencher: Bencher) { |
72 | | - let data = text_data::generate_by_size(SIZE_MB, 80); |
73 | | - bench_tr_with_stdin(bencher, &data, &["aeiou", "AEIOU"]); |
74 | | -} |
| 62 | + /// Multi-character set translation. Falls through to the |
| 63 | + /// 256-byte translation table path (no fast path applies). |
| 64 | + #[divan::bench] |
| 65 | + fn tr_multi_char_translate(bencher: Bencher) { |
| 66 | + let data = text_data::generate_by_size(SIZE_MB, 80); |
| 67 | + bench_tr_with_stdin(bencher, &data, &["aeiou", "AEIOU"]); |
| 68 | + } |
75 | 69 |
|
76 | | -/// Delete an ASCII range — covers the deletion path. |
77 | | -#[cfg(unix)] |
78 | | -#[divan::bench] |
79 | | -fn tr_delete_ascii_range(bencher: Bencher) { |
80 | | - let data = text_data::generate_by_size(SIZE_MB, 80); |
81 | | - bench_tr_with_stdin(bencher, &data, &["-d", "a-z"]); |
| 70 | + /// Delete an ASCII range — covers the deletion path. |
| 71 | + #[divan::bench] |
| 72 | + fn tr_delete_ascii_range(bencher: Bencher) { |
| 73 | + let data = text_data::generate_by_size(SIZE_MB, 80); |
| 74 | + bench_tr_with_stdin(bencher, &data, &["-d", "a-z"]); |
| 75 | + } |
82 | 76 | } |
83 | 77 |
|
84 | 78 | fn main() { |
|
0 commit comments