mirror of
https://github.com/uutils/tar.git
synced 2026-06-10 16:14:35 -07:00
Add CodSpeed performance benchmarks
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
name: CodSpeed
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
pull_request:
|
||||
# `workflow_dispatch` allows CodSpeed to trigger backtest
|
||||
# performance analysis in order to generate initial data.
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
CARGO_INCREMENTAL: "0"
|
||||
|
||||
jobs:
|
||||
codspeed:
|
||||
name: Run benchmarks
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup rust toolchain
|
||||
run: |
|
||||
rustup toolchain install stable --profile minimal
|
||||
rustup default stable
|
||||
|
||||
- name: Install cargo-codspeed
|
||||
run: cargo install cargo-codspeed --locked
|
||||
|
||||
- name: Build the benchmark target(s)
|
||||
run: cargo codspeed build
|
||||
|
||||
- name: Run the benchmarks
|
||||
uses: CodSpeedHQ/action@v4
|
||||
with:
|
||||
mode: simulation
|
||||
run: cargo codspeed run
|
||||
Generated
+290
-18
File diff suppressed because it is too large
Load Diff
@@ -68,6 +68,7 @@ tar = { optional = true, version = "0.0.1", package = "uu_tar", path = "src/uu/t
|
||||
|
||||
[dev-dependencies]
|
||||
chrono = { workspace = true }
|
||||
divan = { version = "4.7.0", package = "codspeed-divan-compat" }
|
||||
pretty_assertions = "1"
|
||||
rand = { workspace = true }
|
||||
regex = { workspace = true }
|
||||
@@ -87,6 +88,10 @@ rlimit = "0.11.0"
|
||||
phf_codegen = { workspace = true }
|
||||
|
||||
|
||||
[[bench]]
|
||||
name = "bench_tar"
|
||||
harness = false
|
||||
|
||||
[[bin]]
|
||||
name = "tarapp"
|
||||
path = "src/bin/tarapp.rs"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
[](https://deps.rs/repo/github/uutils/tar)
|
||||
|
||||
[](https://codecov.io/gh/uutils/tar)
|
||||
[](https://app.codspeed.io/uutils/tar?utm_source=badge)
|
||||
|
||||
# tar
|
||||
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
// Benchmarks for the uutils tar implementation.
|
||||
//
|
||||
// These benchmarks exercise the core archive operations (create, list, extract)
|
||||
// at various scales to track performance over time.
|
||||
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
use tar::operations;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn main() {
|
||||
divan::main();
|
||||
}
|
||||
|
||||
/// Create `count` files of `size` bytes each inside `dir`.
|
||||
fn create_sample_files(dir: &Path, count: usize, size: usize) {
|
||||
let content = vec![b'A'; size];
|
||||
for i in 0..count {
|
||||
let path = dir.join(format!("file_{i}.txt"));
|
||||
let mut f = File::create(&path).unwrap();
|
||||
f.write_all(&content).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
/// Collect all regular file paths inside `dir` (non-recursive).
|
||||
fn collect_files(dir: &Path) -> Vec<PathBuf> {
|
||||
let mut paths: Vec<PathBuf> = fs::read_dir(dir)
|
||||
.unwrap()
|
||||
.filter_map(|e| e.ok())
|
||||
.map(|e| e.path())
|
||||
.filter(|p| p.is_file())
|
||||
.collect();
|
||||
paths.sort();
|
||||
paths
|
||||
}
|
||||
|
||||
/// Build a tar archive at `archive_path` from all files in `source_dir`.
|
||||
fn build_archive(archive_path: &Path, source_dir: &Path) {
|
||||
let files = collect_files(source_dir);
|
||||
let refs: Vec<&Path> = files.iter().map(|p| p.as_path()).collect();
|
||||
operations::create::create_archive(archive_path, &refs, false, false).unwrap();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Create benchmarks
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[divan::bench]
|
||||
fn create_archive_10_files(bencher: divan::Bencher) {
|
||||
let source = TempDir::new().unwrap();
|
||||
create_sample_files(source.path(), 10, 4_096);
|
||||
let files = collect_files(source.path());
|
||||
|
||||
let out = TempDir::new().unwrap();
|
||||
let archive_path = out.path().join("bench.tar");
|
||||
|
||||
bencher.bench_local(|| {
|
||||
let refs: Vec<&Path> = files.iter().map(|p| p.as_path()).collect();
|
||||
operations::create::create_archive(&archive_path, &refs, false, false).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[divan::bench]
|
||||
fn create_archive_100_files(bencher: divan::Bencher) {
|
||||
let source = TempDir::new().unwrap();
|
||||
create_sample_files(source.path(), 100, 4_096);
|
||||
let files = collect_files(source.path());
|
||||
|
||||
let out = TempDir::new().unwrap();
|
||||
let archive_path = out.path().join("bench.tar");
|
||||
|
||||
bencher.bench_local(|| {
|
||||
let refs: Vec<&Path> = files.iter().map(|p| p.as_path()).collect();
|
||||
operations::create::create_archive(&archive_path, &refs, false, false).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[divan::bench]
|
||||
fn create_archive_directory(bencher: divan::Bencher) {
|
||||
let source = TempDir::new().unwrap();
|
||||
let sub = source.path().join("data");
|
||||
fs::create_dir_all(&sub).unwrap();
|
||||
create_sample_files(&sub, 30, 4_096);
|
||||
|
||||
let out = TempDir::new().unwrap();
|
||||
let archive_path = out.path().join("bench.tar");
|
||||
|
||||
bencher.bench_local(|| {
|
||||
operations::create::create_archive(&archive_path, &[sub.as_path()], false, false).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// List benchmarks
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[divan::bench]
|
||||
fn list_archive_50_files(bencher: divan::Bencher) {
|
||||
let source = TempDir::new().unwrap();
|
||||
create_sample_files(source.path(), 50, 4_096);
|
||||
let archive_dir = TempDir::new().unwrap();
|
||||
let archive_path = archive_dir.path().join("bench.tar");
|
||||
build_archive(&archive_path, source.path());
|
||||
|
||||
bencher.bench_local(|| {
|
||||
operations::list::list_archive(&archive_path, false).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[divan::bench]
|
||||
fn list_archive_verbose_50_files(bencher: divan::Bencher) {
|
||||
let source = TempDir::new().unwrap();
|
||||
create_sample_files(source.path(), 50, 4_096);
|
||||
let archive_dir = TempDir::new().unwrap();
|
||||
let archive_path = archive_dir.path().join("bench.tar");
|
||||
build_archive(&archive_path, source.path());
|
||||
|
||||
bencher.bench_local(|| {
|
||||
operations::list::list_archive(&archive_path, true).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Extract benchmarks
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[divan::bench]
|
||||
fn extract_archive_20_files(bencher: divan::Bencher) {
|
||||
let source = TempDir::new().unwrap();
|
||||
create_sample_files(source.path(), 20, 4_096);
|
||||
let archive_dir = TempDir::new().unwrap();
|
||||
let archive_path = archive_dir.path().join("bench.tar");
|
||||
build_archive(&archive_path, source.path());
|
||||
|
||||
let original_dir = std::env::current_dir().unwrap();
|
||||
bencher
|
||||
.with_inputs(|| TempDir::new().unwrap())
|
||||
.bench_local_values(|extract_dir| {
|
||||
std::env::set_current_dir(extract_dir.path()).unwrap();
|
||||
operations::extract::extract_archive(&archive_path, false).unwrap();
|
||||
});
|
||||
std::env::set_current_dir(original_dir).unwrap();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CLI parsing benchmark
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[divan::bench]
|
||||
fn build_cli_command(bencher: divan::Bencher) {
|
||||
bencher.bench_local(|| {
|
||||
divan::black_box(tar::uu_app());
|
||||
});
|
||||
}
|
||||
@@ -4,9 +4,9 @@
|
||||
// file that was distributed with this source code.
|
||||
|
||||
pub mod errors;
|
||||
mod operations;
|
||||
pub mod operations;
|
||||
|
||||
use clap::{arg, crate_version, ArgAction, Command};
|
||||
use clap::{ArgAction, Command, arg, crate_version};
|
||||
use std::path::{Path, PathBuf};
|
||||
use uucore::error::UResult;
|
||||
use uucore::format_usage;
|
||||
|
||||
Reference in New Issue
Block a user