From 013f732b6bea2568af18990bbfe52f3bac93ab7e Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 15 Aug 2026 11:47:06 +0200 Subject: [PATCH] du: warm OS page cache before timing in benchmarks First iterations run cold (page cache empty) and subsequent ones hot, creating a bimodal distribution and spurious CI regression alerts. Add warm_cache() to run one untimed traversal before measurement starts. --- src/uu/du/benches/du_bench.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/uu/du/benches/du_bench.rs b/src/uu/du/benches/du_bench.rs index 7812e3ba3fa..0d9959325b7 100644 --- a/src/uu/du/benches/du_bench.rs +++ b/src/uu/du/benches/du_bench.rs @@ -3,7 +3,7 @@ // 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::{black_box, Bencher}; use tempfile::TempDir; use uu_du::uumain; use uucore::benchmark::{fs_tree, get_bench_args}; @@ -59,43 +59,51 @@ fn du_human_balanced_tree( } */ -/// Benchmark du on wide directory structures (many files/dirs, shallow) +/// Run a throwaway traversal to warm the OS page/inode cache before timing. +fn warm_cache(path: &std::path::Path) { + let _ = black_box(uumain(get_bench_args(&[&path]).into_iter())); +} + +/// Benchmark du on wide directory structures (many files/dirs, shallow). #[divan::bench(args = [(5000, 500)])] fn du_wide_tree(bencher: Bencher, (total_files, total_dirs): (usize, usize)) { let temp_dir = TempDir::new().unwrap(); let temp_path = temp_dir.path(); fs_tree::create_wide_tree(temp_path, total_files, total_dirs); + warm_cache(temp_path); bencher .with_inputs(|| get_bench_args(&[&temp_path]).into_iter()) .bench_values(|args| black_box(uumain(args))); } -/// Benchmark du -a on wide directory structures +/// Benchmark du -a on wide directory structures. #[divan::bench(args = [(5000, 500)])] fn du_all_wide_tree(bencher: Bencher, (total_files, total_dirs): (usize, usize)) { let temp_dir = TempDir::new().unwrap(); let temp_path = temp_dir.path(); fs_tree::create_wide_tree(temp_path, total_files, total_dirs); + warm_cache(temp_path); bencher .with_inputs(|| get_bench_args(&[&"-a", &temp_path]).into_iter()) .bench_values(|args| black_box(uumain(args))); } -/// Benchmark du on deep directory structures +/// Benchmark du on deep directory structures. #[divan::bench(args = [(100, 3)])] fn du_deep_tree(bencher: Bencher, (depth, files_per_level): (usize, usize)) { let temp_dir = TempDir::new().unwrap(); let temp_path = temp_dir.path(); fs_tree::create_deep_tree(temp_path, depth, files_per_level); + warm_cache(temp_path); bencher .with_inputs(|| get_bench_args(&[&temp_path]).into_iter()) .bench_values(|args| black_box(uumain(args))); } -/// Benchmark du -s (summarize) on balanced tree +/// Benchmark du -s (summarize) on balanced tree. #[divan::bench(args = [(5, 4, 10)])] fn du_summarize_balanced_tree( bencher: Bencher, @@ -104,6 +112,7 @@ fn du_summarize_balanced_tree( let temp_dir = TempDir::new().unwrap(); let temp_path = temp_dir.path(); fs_tree::create_balanced_tree(temp_path, depth, dirs_per_level, files_per_dir); + warm_cache(temp_path); bencher .with_inputs(|| get_bench_args(&[&"-s", &temp_path]).into_iter())