Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
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
1 change: 1 addition & 0 deletions .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jobs:
- { package: uu_cksum }
- { package: uu_cp }
- { package: uu_cut }
- { package: uu_dd }
- { package: uu_du }
- { package: uu_expand }
- { package: uu_fold }
Expand Down
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/uu/dd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,12 @@ nix = { workspace = true, features = ["fs"] }
[[bin]]
name = "dd"
path = "src/main.rs"

[dev-dependencies]
divan = { workspace = true }
tempfile = { workspace = true }
uucore = { workspace = true, features = ["benchmark"] }

[[bench]]
name = "dd_bench"
harness = false
266 changes: 266 additions & 0 deletions src/uu/dd/benches/dd_bench.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
// This file is part of the uutils coreutils package.
//
// 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::fs::{self, File};
use std::io::Write;
use std::path::Path;
use tempfile::TempDir;
use uu_dd::uumain;
use uucore::benchmark::run_util_function;

fn create_test_file(path: &Path, size_mb: usize) {
let buffer = vec![b'x'; size_mb * 1024 * 1024];
let mut file = File::create(path).unwrap();
file.write_all(&buffer).unwrap();
file.sync_all().unwrap();
}

fn remove_file(path: &Path) {
if path.exists() {
fs::remove_file(path).unwrap();
}
}

/// Benchmark basic dd copy with default settings
#[divan::bench(args = [32])]
fn dd_copy_default(bencher: Bencher, size_mb: usize) {
let temp_dir = TempDir::new().unwrap();
let input = temp_dir.path().join("input.bin");
let output = temp_dir.path().join("output.bin");

create_test_file(&input, size_mb);

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

bencher.bench(|| {
remove_file(&output);
black_box(run_util_function(
uumain,
&[
&format!("if={input_str}"),
&format!("of={output_str}"),
"status=none",
],
));
});
}

/// Benchmark dd copy with 4KB block size (common page size)
#[divan::bench(args = [24])]
fn dd_copy_4k_blocks(bencher: Bencher, size_mb: usize) {
let temp_dir = TempDir::new().unwrap();
let input = temp_dir.path().join("input.bin");
let output = temp_dir.path().join("output.bin");

create_test_file(&input, size_mb);

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

bencher.bench(|| {
remove_file(&output);
black_box(run_util_function(
uumain,
&[
&format!("if={input_str}"),
&format!("of={output_str}"),
"bs=4K",
"status=none",
],
));
});
}

/// Benchmark dd copy with 64KB block size
#[divan::bench(args = [64])]
fn dd_copy_64k_blocks(bencher: Bencher, size_mb: usize) {
let temp_dir = TempDir::new().unwrap();
let input = temp_dir.path().join("input.bin");
let output = temp_dir.path().join("output.bin");

create_test_file(&input, size_mb);

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

bencher.bench(|| {
remove_file(&output);
black_box(run_util_function(
uumain,
&[
&format!("if={input_str}"),
&format!("of={output_str}"),
"bs=64K",
"status=none",
],
));
});
}

/// Benchmark dd copy with 1MB block size
#[divan::bench(args = [128])]
fn dd_copy_1m_blocks(bencher: Bencher, size_mb: usize) {
let temp_dir = TempDir::new().unwrap();
let input = temp_dir.path().join("input.bin");
let output = temp_dir.path().join("output.bin");

create_test_file(&input, size_mb);

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

bencher.bench(|| {
remove_file(&output);
black_box(run_util_function(
uumain,
&[
&format!("if={input_str}"),
&format!("of={output_str}"),
"bs=1M",
"status=none",
],
));
});
}

/// Benchmark dd copy with separate input and output block sizes
#[divan::bench(args = [48])]
fn dd_copy_separate_blocks(bencher: Bencher, size_mb: usize) {
let temp_dir = TempDir::new().unwrap();
let input = temp_dir.path().join("input.bin");
let output = temp_dir.path().join("output.bin");

create_test_file(&input, size_mb);

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

bencher.bench(|| {
remove_file(&output);
black_box(run_util_function(
uumain,
&[
&format!("if={input_str}"),
&format!("of={output_str}"),
"ibs=8K",
"obs=16K",
"status=none",
],
));
});
}

/// Benchmark dd with count limit (partial copy)
#[divan::bench(args = [32])]
fn dd_copy_partial(bencher: Bencher, size_mb: usize) {
let temp_dir = TempDir::new().unwrap();
let input = temp_dir.path().join("input.bin");
let output = temp_dir.path().join("output.bin");

create_test_file(&input, size_mb);

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

bencher.bench(|| {
remove_file(&output);
black_box(run_util_function(
uumain,
&[
&format!("if={input_str}"),
&format!("of={output_str}"),
"bs=4K",
"count=1024",
"status=none",
],
));
});
}

/// Benchmark dd with skip (seeking in input)
#[divan::bench(args = [48])]
fn dd_copy_with_skip(bencher: Bencher, size_mb: usize) {
let temp_dir = TempDir::new().unwrap();
let input = temp_dir.path().join("input.bin");
let output = temp_dir.path().join("output.bin");

create_test_file(&input, size_mb);

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

bencher.bench(|| {
remove_file(&output);
black_box(run_util_function(
uumain,
&[
&format!("if={input_str}"),
&format!("of={output_str}"),
"bs=4K",
"skip=256",
"status=none",
],
));
});
}

/// Benchmark dd with seek (seeking in output)
#[divan::bench(args = [48])]
fn dd_copy_with_seek(bencher: Bencher, size_mb: usize) {
let temp_dir = TempDir::new().unwrap();
let input = temp_dir.path().join("input.bin");
let output = temp_dir.path().join("output.bin");

create_test_file(&input, size_mb);

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

bencher.bench(|| {
remove_file(&output);
black_box(run_util_function(
uumain,
&[
&format!("if={input_str}"),
&format!("of={output_str}"),
"bs=4K",
"seek=256",
"status=none",
],
));
});
}

/// Benchmark dd with different block sizes for comparison
#[divan::bench(args = [32])]
fn dd_copy_8k_blocks(bencher: Bencher, size_mb: usize) {
let temp_dir = TempDir::new().unwrap();
let input = temp_dir.path().join("input.bin");
let output = temp_dir.path().join("output.bin");

create_test_file(&input, size_mb);

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

bencher.bench(|| {
remove_file(&output);
black_box(run_util_function(
uumain,
&[
&format!("if={input_str}"),
&format!("of={output_str}"),
"bs=8K",
"status=none",
],
));
});
}

fn main() {
divan::main();
}
Loading