Add CodSpeed performance benchmarks

This commit is contained in:
codspeed-hq[bot]
2026-06-04 19:44:08 +00:00
committed by GitHub
parent 4986a8460c
commit 0faed0baeb
6 changed files with 495 additions and 20 deletions
+42
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+5
View File
@@ -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"
+1
View File
@@ -4,6 +4,7 @@
[![dependency status](https://deps.rs/repo/github/uutils/tar/status.svg)](https://deps.rs/repo/github/uutils/tar)
[![CodeCov](https://codecov.io/gh/uutils/tar/branch/master/graph/badge.svg)](https://codecov.io/gh/uutils/tar)
[![CodSpeed](https://img.shields.io/endpoint?url=https://codspeed.io/badge.json)](https://app.codspeed.io/uutils/tar?utm_source=badge)
# tar
+155
View File
@@ -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());
});
}
+2 -2
View File
@@ -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;