mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 14:01:37 +00:00
Replace `git status --porcelain -uall` with `git diff-index` (6x faster for tracked changes) and `git ls-files --others` for untracked files. Add mtime-based caching keyed on .git/index mtime, HEAD SHA, and tree mutation cursor to make repeated calls near-instant (~14ms vs ~1000ms). Empty changesets are never cached to ensure external file edits are always detected on the next query. Falls back to git status for repos with no commits (empty repo edge case).
165 lines
4.6 KiB
Rust
165 lines
4.6 KiB
Rust
use std::path::PathBuf;
|
|
use std::process::Command;
|
|
use std::time::Instant;
|
|
|
|
use criterion::{criterion_group, criterion_main, Criterion};
|
|
|
|
fn test_repo() -> PathBuf {
|
|
let home = std::env::var("HOME").expect("HOME not set");
|
|
let path = PathBuf::from(home).join("workspace/escape-tsunami-for-brainrots");
|
|
assert!(
|
|
path.join(".git").is_dir(),
|
|
"Test repo not found at {}",
|
|
path.display()
|
|
);
|
|
path
|
|
}
|
|
|
|
fn bench_git_status_uall(c: &mut Criterion) {
|
|
let repo = test_repo();
|
|
|
|
let mut group = c.benchmark_group("git_changed_files");
|
|
group.sample_size(10);
|
|
|
|
group.bench_function("git_status_porcelain_uall", |b| {
|
|
b.iter(|| {
|
|
Command::new("git")
|
|
.args([
|
|
"status",
|
|
"--porcelain",
|
|
"--no-renames",
|
|
"-uall",
|
|
"--",
|
|
"src",
|
|
])
|
|
.current_dir(&repo)
|
|
.output()
|
|
.unwrap()
|
|
})
|
|
});
|
|
|
|
group.bench_function("git_diff_index_HEAD", |b| {
|
|
b.iter(|| {
|
|
Command::new("git")
|
|
.args([
|
|
"--no-optional-locks",
|
|
"diff-index",
|
|
"--name-only",
|
|
"HEAD",
|
|
"--",
|
|
"src",
|
|
])
|
|
.current_dir(&repo)
|
|
.output()
|
|
.unwrap()
|
|
})
|
|
});
|
|
|
|
group.bench_function("git_ls_files_others", |b| {
|
|
b.iter(|| {
|
|
Command::new("git")
|
|
.args([
|
|
"--no-optional-locks",
|
|
"ls-files",
|
|
"--others",
|
|
"--exclude-standard",
|
|
"--",
|
|
"src",
|
|
])
|
|
.current_dir(&repo)
|
|
.output()
|
|
.unwrap()
|
|
})
|
|
});
|
|
|
|
group.bench_function("diff_index_plus_ls_files_parallel", |b| {
|
|
b.iter(|| {
|
|
let repo_a = repo.clone();
|
|
let repo_b = repo.clone();
|
|
std::thread::scope(|s| {
|
|
let h1 = s.spawn(move || {
|
|
Command::new("git")
|
|
.args([
|
|
"--no-optional-locks",
|
|
"diff-index",
|
|
"--name-only",
|
|
"HEAD",
|
|
"--",
|
|
"src",
|
|
])
|
|
.current_dir(&repo_a)
|
|
.output()
|
|
.unwrap()
|
|
});
|
|
let h2 = s.spawn(move || {
|
|
Command::new("git")
|
|
.args([
|
|
"--no-optional-locks",
|
|
"ls-files",
|
|
"--others",
|
|
"--exclude-standard",
|
|
"--",
|
|
"src",
|
|
])
|
|
.current_dir(&repo_b)
|
|
.output()
|
|
.unwrap()
|
|
});
|
|
(h1.join().unwrap(), h2.join().unwrap())
|
|
})
|
|
})
|
|
});
|
|
|
|
group.bench_function("cache_staleness_check", |b| {
|
|
b.iter(|| {
|
|
let index_path = repo.join(".git/index");
|
|
let mtime = std::fs::metadata(&index_path).unwrap().modified().unwrap();
|
|
let head = Command::new("git")
|
|
.args(["rev-parse", "HEAD"])
|
|
.current_dir(&repo)
|
|
.output()
|
|
.unwrap();
|
|
(mtime, head)
|
|
})
|
|
});
|
|
|
|
group.finish();
|
|
|
|
eprintln!("\n--- Quick wall-clock summary ---");
|
|
let runs: &[(&str, &[&str])] = &[
|
|
(
|
|
"git status -uall (current)",
|
|
&[
|
|
"status",
|
|
"--porcelain",
|
|
"--no-renames",
|
|
"-uall",
|
|
"--",
|
|
"src",
|
|
],
|
|
),
|
|
(
|
|
"git diff-index HEAD (new)",
|
|
&[
|
|
"--no-optional-locks",
|
|
"diff-index",
|
|
"--name-only",
|
|
"HEAD",
|
|
"--",
|
|
"src",
|
|
],
|
|
),
|
|
];
|
|
for (label, args) in runs {
|
|
let t = Instant::now();
|
|
Command::new("git")
|
|
.args(*args)
|
|
.current_dir(&repo)
|
|
.output()
|
|
.unwrap();
|
|
eprintln!(" {}: {}ms", label, t.elapsed().as_millis());
|
|
}
|
|
}
|
|
|
|
criterion_group!(benches, bench_git_status_uall);
|
|
criterion_main!(benches);
|