+
Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 22 additions & 26 deletions src/uu/base64/benches/base64_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,67 +3,63 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

use divan::{Bencher, black_box};
use divan::Bencher;
use std::ffi::OsString;
use uu_base64::uumain;
use uucore::benchmark::{create_test_file, run_util_function, text_data};

fn create_tmp_file(size_mb: usize) -> String {
let temp_dir = tempfile::tempdir().unwrap();
let data = text_data::generate_by_size(size_mb, 80);
let file_path = create_test_file(&data, temp_dir.path());
String::from(file_path.to_str().unwrap())
}
use uucore::benchmark::{bench_util, create_test_file, run_util_function, text_data};

/// Benchmark for base64 encoding
#[divan::bench()]
fn b64_encode_synthetic(bencher: Bencher) {
let file_path_str = &create_tmp_file(5_000);

bencher.bench(|| {
black_box(run_util_function(uumain, &[file_path_str]));
});
let data = text_data::generate_by_size(5_000, 80);
bench_util(bencher, data, &[], uumain);
}

// Benchmark for base64 decoding
#[divan::bench()]
fn b64_decode_synthetic(bencher: Bencher) {
let temp_dir = tempfile::tempdir().unwrap();
let file_path_str = &create_tmp_file(5_000);
let in_file = create_test_file(b"", temp_dir.path());
let in_file_str = in_file.to_str().unwrap();
let source_data = text_data::generate_by_size(5_000, 80);
let source_file = create_test_file(&source_data, temp_dir.path());
let encoded_file = create_test_file(b"", temp_dir.path());
let encoded_file_str = encoded_file.to_str().unwrap();

// First encode the data to create the test input
uumain(
[
OsString::from(file_path_str),
OsString::from(format!(">{in_file_str}")),
OsString::from(source_file.to_str().unwrap()),
OsString::from(format!(">{encoded_file_str}")),
]
.iter()
.map(|x| (*x).clone()),
);

bencher.bench(|| {
black_box(run_util_function(uumain, &["-d", in_file_str]));
divan::black_box(run_util_function(uumain, &["-d", encoded_file_str]));
});
}

// Benchmark different file sizes for base64 decoding ignoring garbage characters
#[divan::bench()]
fn b64_decode_ignore_garbage_synthetic(bencher: Bencher) {
let temp_dir = tempfile::tempdir().unwrap();
let file_path_str = &create_tmp_file(5_000);
let in_file = create_test_file(b"", temp_dir.path());
let in_file_str = in_file.to_str().unwrap();
let source_data = text_data::generate_by_size(5_000, 80);
let source_file = create_test_file(&source_data, temp_dir.path());
let encoded_file = create_test_file(b"", temp_dir.path());
let encoded_file_str = encoded_file.to_str().unwrap();

// First encode the data to create the test input
uumain(
[
OsString::from(file_path_str),
OsString::from(format!(">{in_file_str}")),
OsString::from(source_file.to_str().unwrap()),
OsString::from(format!(">{encoded_file_str}")),
]
.iter()
.map(|x| (*x).clone()),
);

bencher.bench(|| {
black_box(run_util_function(uumain, &["-d", "-i", in_file_str]));
divan::black_box(run_util_function(uumain, &["-d", "-i", encoded_file_str]));
});
}

Expand Down
34 changes: 6 additions & 28 deletions src/uu/expand/benches/expand_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,22 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

use divan::{Bencher, black_box};
use std::fmt::Write;
use divan::Bencher;
use uu_expand::uumain;
use uucore::benchmark::{create_test_file, run_util_function};

/// Helper function to run expand benchmark with generated data
fn bench_expand(bencher: Bencher, data: impl AsRef<[u8]>, args: &[&str]) {
let temp_dir = tempfile::tempdir().unwrap();
let file_path = create_test_file(data.as_ref(), temp_dir.path());
let file_path_str = file_path.to_str().unwrap();

let mut all_args = vec![];
all_args.extend_from_slice(args);
all_args.push(file_path_str);

bencher.bench(|| {
black_box(run_util_function(uumain, &all_args));
});
}
use uucore::benchmark::{bench_util, generate_multi_tab_text, generate_tabbed_text};

/// Benchmark expanding tabs on files with many short lines
#[divan::bench(args = [100_000])]
fn expand_many_lines(bencher: Bencher, num_lines: usize) {
let data = (0..num_lines).fold(String::new(), |mut acc, i| {
writeln!(&mut acc, "line{i}\tvalue{}\tdata{}", i * 2, i * 3).unwrap();
acc
});
bench_expand(bencher, data, &[]);
let data = generate_tabbed_text(num_lines);
bench_util(bencher, data, &[], uumain);
}

/// Benchmark expanding tabs with custom tab stops
#[divan::bench(args = [50_000])]
fn expand_custom_tabstops(bencher: Bencher, num_lines: usize) {
let data = (0..num_lines).fold(String::new(), |mut acc, i| {
writeln!(&mut acc, "a\tb\tc\td\te{i}").unwrap();
acc
});
bench_expand(bencher, data, &["--tabs=4,8,12"]);
let data = generate_multi_tab_text(num_lines);
bench_util(bencher, data, &["--tabs=4,8,12"], uumain);
}

fn main() {
Expand Down
20 changes: 4 additions & 16 deletions src/uu/fold/benches/fold_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,26 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

use divan::{Bencher, black_box};
use divan::Bencher;
use std::fmt::Write;
use uu_fold::uumain;
use uucore::benchmark::{create_test_file, run_util_function};
use uucore::benchmark::bench_util;

/// Benchmark folding many short lines
#[divan::bench(args = [100_000])]
fn fold_many_lines(bencher: Bencher, num_lines: usize) {
let temp_dir = tempfile::tempdir().unwrap();
// Create long lines that need folding
let data = (0..num_lines)
.fold(String::new(), |mut acc, i| {
writeln!(&mut acc, "This is a very long line number {i} that definitely needs to be folded at the default width of 80 columns").unwrap();
acc
});
let file_path = create_test_file(data.as_bytes(), temp_dir.path());
let file_path_str = file_path.to_str().unwrap();

bencher.bench(|| {
black_box(run_util_function(uumain, &[file_path_str]));
});
bench_util(bencher, data, &[], uumain);
}

/// Benchmark folding with custom width
#[divan::bench(args = [50_000])]
fn fold_custom_width(bencher: Bencher, num_lines: usize) {
let temp_dir = tempfile::tempdir().unwrap();
let data = (0..num_lines).fold(String::new(), |mut acc, i| {
writeln!(
&mut acc,
Expand All @@ -38,12 +31,7 @@ fn fold_custom_width(bencher: Bencher, num_lines: usize) {
.unwrap();
acc
});
let file_path = create_test_file(data.as_bytes(), temp_dir.path());
let file_path_str = file_path.to_str().unwrap();

bencher.bench(|| {
black_box(run_util_function(uumain, &["-w", "40", file_path_str]));
});
bench_util(bencher, data, &["-w", "40"], uumain);
}

fn main() {
Expand Down
20 changes: 4 additions & 16 deletions src/uu/nl/benches/nl_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,22 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

use divan::{Bencher, black_box};
use divan::Bencher;
use uu_nl::uumain;
use uucore::benchmark::{create_test_file, run_util_function, text_data};
use uucore::benchmark::{bench_util, text_data};

/// Benchmark numbering many lines (default mode - most common use case)
#[divan::bench(args = [100_000])]
fn nl_many_lines(bencher: Bencher, num_lines: usize) {
let temp_dir = tempfile::tempdir().unwrap();
let data = text_data::generate_by_lines(num_lines, 80);
let file_path = create_test_file(&data, temp_dir.path());
let file_path_str = file_path.to_str().unwrap();

bencher.bench(|| {
black_box(run_util_function(uumain, &[file_path_str]));
});
bench_util(bencher, data, &[], uumain);
}

/// Benchmark large file with -ba option (number all lines - most common argument)
#[divan::bench(args = [10])]
fn nl_large_file(bencher: Bencher, size_mb: usize) {
let temp_dir = tempfile::tempdir().unwrap();
let data = text_data::generate_by_size(size_mb, 80);
let file_path = create_test_file(&data, temp_dir.path());
let file_path_str = file_path.to_str().unwrap();

bencher.bench(|| {
black_box(run_util_function(uumain, &["-ba", file_path_str]));
});
bench_util(bencher, data, &["-ba"], uumain);
}

fn main() {
Expand Down
33 changes: 4 additions & 29 deletions src/uu/unexpand/benches/unexpand_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,25 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

use divan::{Bencher, black_box};
use divan::Bencher;
use uu_unexpand::uumain;
use uucore::benchmark::{create_test_file, run_util_function};

/// Generate text data with leading spaces (typical unexpand use case)
fn generate_indented_text(num_lines: usize) -> Vec<u8> {
let mut data = Vec::new();
for i in 0..num_lines {
// Add varying amounts of leading spaces (4, 8, 12, etc.)
let indent = (i % 4 + 1) * 4;
data.extend(vec![b' '; indent]);
data.extend_from_slice(b"This is a line of text with leading spaces\n");
}
data
}
use uucore::benchmark::{bench_util, generate_indented_text};

/// Benchmark unexpanding many lines with leading spaces (most common use case)
#[divan::bench(args = [100_000])]
fn unexpand_many_lines(bencher: Bencher, num_lines: usize) {
let temp_dir = tempfile::tempdir().unwrap();
let data = generate_indented_text(num_lines);
let file_path = create_test_file(&data, temp_dir.path());
let file_path_str = file_path.to_str().unwrap();

bencher.bench(|| {
black_box(run_util_function(uumain, &[file_path_str]));
});
bench_util(bencher, data, &[], uumain);
}

/// Benchmark large file with spaces (tests performance on large files)
#[divan::bench(args = [10])]
fn unexpand_large_file(bencher: Bencher, size_mb: usize) {
let temp_dir = tempfile::tempdir().unwrap();

// Generate approximately size_mb worth of indented lines
let line_size = 50; // approximate bytes per line
let num_lines = (size_mb * 1024 * 1024) / line_size;
let data = generate_indented_text(num_lines);
let file_path = create_test_file(&data, temp_dir.path());
let file_path_str = file_path.to_str().unwrap();

bencher.bench(|| {
black_box(run_util_function(uumain, &[file_path_str]));
});
bench_util(bencher, data, &[], uumain);
}

fn main() {
Expand Down
83 changes: 11 additions & 72 deletions src/uu/uniq/benches/uniq_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,11 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

use divan::{Bencher, black_box};
use divan::Bencher;
use uu_uniq::uumain;
use uucore::benchmark::{run_util_function, setup_test_file};

/// Generate data with many consecutive duplicate lines
/// This directly tests the core optimization of PR #8703 - avoiding allocations when comparing lines
fn generate_duplicate_heavy_data(num_groups: usize, duplicates_per_group: usize) -> Vec<u8> {
let mut data = Vec::new();

for group in 0..num_groups {
// Generate a line with realistic content
let line = format!(
"Line content for group {group:06} with additional text to make it more realistic for testing performance\n"
);

// Repeat the line multiple times (this is what PR #8703 optimizes)
for _ in 0..duplicates_per_group {
data.extend_from_slice(line.as_bytes());
}
}

data
}
use uucore::benchmark::{
bench_util, generate_case_variation_data, generate_duplicate_heavy_data, setup_test_file,
};

/// Benchmark 1: Heavy duplicates - the main optimization target
/// Many consecutive duplicate lines that stress the line comparison optimization
Expand All @@ -40,7 +22,10 @@ fn uniq_heavy_duplicates(bencher: Bencher, num_lines: usize) {
let file_path_str = file_path.to_str().unwrap();

bencher.bench(|| {
black_box(run_util_function(uumain, &[file_path_str]));
divan::black_box(uucore::benchmark::run_util_function(
uumain,
&[file_path_str],
));
});
}

Expand All @@ -51,61 +36,15 @@ fn uniq_with_count(bencher: Bencher, num_lines: usize) {
// Create more groups with fewer duplicates for varied counting
let num_groups = num_lines / 100;
let data = generate_duplicate_heavy_data(num_groups, 100);
let file_path = setup_test_file(&data);
let file_path_str = file_path.to_str().unwrap();

bencher.bench(|| {
black_box(run_util_function(uumain, &["-c", file_path_str]));
});
bench_util(bencher, data, &["-c"], uumain);
}

/// Benchmark 3: Case-insensitive comparison with duplicates
/// Tests the -i flag which requires case folding during comparison
#[divan::bench(args = [10_000])]
fn uniq_case_insensitive(bencher: Bencher, num_lines: usize) {
let mut data = Vec::new();
let words = [
"Hello",
"WORLD",
"Testing",
"UNIQ",
"Benchmark",
"Performance",
];

// Generate groups of case variations
for i in 0..num_lines {
let word = words[(i / 50) % words.len()];

// Create case variations that should be treated as duplicates with -i
let variation = match i % 4 {
0 => word.to_lowercase(),
1 => word.to_uppercase(),
2 => word.to_string(),
_ => {
// Mixed case
word.chars()
.enumerate()
.map(|(idx, c)| {
if idx % 2 == 0 {
c.to_lowercase().to_string()
} else {
c.to_uppercase().to_string()
}
})
.collect()
}
};

data.extend_from_slice(format!("{variation}\n").as_bytes());
}

let file_path = setup_test_file(&data);
let file_path_str = file_path.to_str().unwrap();

bencher.bench(|| {
black_box(run_util_function(uumain, &["-i", file_path_str]));
});
let data = generate_case_variation_data(num_lines);
bench_util(bencher, data, &["-i"], uumain);
}

fn main() {
Expand Down
Loading
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载