Trim synthetic overlay benchmarks; record Mac real-pack numbers

The real-pack benchmark on the production resource_root path stays as the
reproducible measurement. On the Mac mini it saves 1.18 s (Faithful 32x) and
5.29 s (FPBR) per startup with the pack enabled.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Ludovic MarieandClaude Opus 5.5 committed 2026-10-15 02:26:46 +02:00
1 parent 1295fccd17
commit cc8744a06b
2 files changed
+10 -193

No files matched your search

-179
View File
@@ -756,185 +756,6 @@ mod tests {
assert!(lock_path(&out).exists());
}
#[test]
#[ignore = "reproducible overlay benchmark; run with --ignored --nocapture"]
fn benchmark_overlay_reuse() {
use std::{hint::black_box, time::Instant};
let f = Fixture::new();
let pack = f.dir_pack("pack");
let mut files = vec![(
"pack.mcmeta".to_owned(),
fs::read(f.0.join("pack/pack.mcmeta")).unwrap(),
)];
// 2,048 overrides (32 MiB), 32 merged language files, 8,192 live
// vanilla textures (128 MiB). Synthetic incompressible payloads approximate
// already-compressed PNG bytes; texture decoding is outside this benchmark.
let mut random = 0x1234_5678u32;
let texture: Vec<u8> = (0..16384)
.map(|_| {
random ^= random << 13;
random ^= random >> 17;
random ^= random << 5;
(random >> 24) as u8
})
.collect();
for i in 0..8192 {
let name = format!("assets/minecraft/textures/block/{i}.png");
f.write(&format!("vanilla/{name}"), &texture);
if i < 2048 {
f.write(&format!("pack/{name}"), &texture);
files.push((name, texture.clone()));
}
}
for i in 0..32 {
let name = format!("assets/minecraft/lang/{i}.json");
let vanilla = serde_json::to_vec(&serde_json::Value::Object(
(0..2000)
.map(|j| {
(
format!("key{j}"),
serde_json::json!(format!("Vanilla translation {j}")),
)
})
.collect(),
))
.unwrap();
let body = serde_json::to_vec(&serde_json::Value::Object(
(0..1000)
.map(|j| {
(
format!("key{j}"),
serde_json::json!(format!("Pack translation {j}")),
)
})
.collect(),
))
.unwrap();
f.write(&format!("vanilla/{name}"), &vanilla);
f.write(&format!("pack/{name}"), &body);
files.push((name, body));
}
let borrowed: Vec<_> = files
.iter()
.map(|(name, body)| (name.as_str(), body.clone()))
.collect();
f.write("pack.zip", &archive(&borrowed, true));
println!(
"fixture ZIP bytes={}",
fs::metadata(f.0.join("pack.zip")).unwrap().len()
);
let zip = packs::pack(
"zip".into(),
Text::empty(),
Source::Zip(f.0.join("pack.zip")),
)
.unwrap();
let median = |mut times: Vec<f64>| {
times.sort_by(f64::total_cmp);
times[times.len() / 2]
};
for (kind, pack) in [("directory", pack), ("deflated zip", zip)] {
f.rebuild_matches(std::slice::from_ref(&pack));
let vanilla = f.0.join("vanilla");
let out = f.0.join("cached");
let mut baseline = Vec::new();
let mut cold = Vec::new();
let mut hit = Vec::new();
for _ in 0..11 {
let start = Instant::now();
build_overlay_uncached(
black_box(&vanilla),
black_box(std::slice::from_ref(&pack)),
black_box(&f.0.join("reference")),
&mut Dependencies::default(),
)
.unwrap();
baseline.push(start.elapsed().as_secs_f64() * 1000.0);
fs::remove_file(marker_path(&out)).unwrap();
let start = Instant::now();
packs::build_overlay(
black_box(&vanilla),
black_box(std::slice::from_ref(&pack)),
black_box(&out),
)
.unwrap();
cold.push(start.elapsed().as_secs_f64() * 1000.0);
let start = Instant::now();
packs::build_overlay(
black_box(&vanilla),
black_box(std::slice::from_ref(&pack)),
black_box(&out),
)
.unwrap();
hit.push(start.elapsed().as_secs_f64() * 1000.0);
assert_eq!(
output_signature(&out).unwrap(),
output_signature(&f.0.join("reference")).unwrap()
);
}
println!(
"{kind}: baseline={:.3} ms cold={:.3} ms unchanged={:.3} ms (11 medians, full validation)",
median(baseline),
median(cold),
median(hit)
);
}
}
#[test]
#[ignore = "content-heavy few-file directory benchmark"]
fn benchmark_content_heavy_directory() {
use std::{hint::black_box, time::Instant};
let f = Fixture::new();
f.write("vanilla/facts.json", b"[]");
let pack = f.dir_pack("pack");
let bytes = vec![42; 8 * 1024 * 1024];
for i in 0..4 {
f.write(&format!("pack/assets/minecraft/textures/{i}.png"), &bytes);
}
let vanilla = f.0.join("vanilla");
let out = f.0.join("cached");
f.rebuild_matches(std::slice::from_ref(&pack));
let mut timings = [Vec::new(), Vec::new(), Vec::new()];
for _ in 0..11 {
let start = Instant::now();
build_overlay_uncached(
black_box(&vanilla),
black_box(std::slice::from_ref(&pack)),
&f.0.join("reference"),
&mut Dependencies::default(),
)
.unwrap();
timings[0].push(start.elapsed().as_secs_f64() * 1000.0);
fs::remove_file(marker_path(&out)).unwrap();
for times in &mut timings[1..] {
let start = Instant::now();
packs::build_overlay(
black_box(&vanilla),
black_box(std::slice::from_ref(&pack)),
black_box(&out),
)
.unwrap();
times.push(start.elapsed().as_secs_f64() * 1000.0);
}
assert_eq!(
output_signature(&out).unwrap(),
output_signature(&f.0.join("reference")).unwrap()
);
}
let medians: Vec<_> = timings
.into_iter()
.map(|mut times| {
times.sort_by(f64::total_cmp);
times[5]
})
.collect();
println!(
"4 x 8 MiB directory textures: baseline={:.3} ms cold={:.3} ms unchanged={:.3} ms (11 medians, full validation)",
medians[0], medians[1], medians[2]
);
}
#[cfg(unix)]
#[test]
fn relative_builder_targets_are_preserved() {
+10 -14
View File
@@ -20,20 +20,17 @@ Linux x86_64/ext4/NVMe, Ryzen 5 5600X, Rust 1.99.0, Cargo `fast`, measured 2026-
Unchanged speedups are approximately 226x, 359x and 775x. Cold overhead on these ZIPs is 0.1–2.6%, replacing the original cache implementation's 73–79% synthetic overhead. This measures overlay assembly and cache validation, excluding scan, texture decoding, total startup and FPS.
Mac mini (M4 Pro, APFS, Rust stable, Cargo `fast`), same harness and packs, measured 2026-10-15 during review while the machine ran other builds:
| ZIP pack | Original rebuild | Cached cold | Unchanged hit | Saved per hit |
| --- | ---: | ---: | ---: | ---: |
| Faithful 32x, 26.3 September 2026 | 1,184.400 ms | 1,295.069 ms | 0.571 ms | 1,183.829 ms |
| FPBR, 1.21.9 R1.3 | 5,292.149 ms | 5,503.965 ms | 0.391 ms | 5,291.758 ms |
Creating thousands of files and links costs far more on macOS than on Linux, so the saving there is seconds per startup with a pack enabled.
Pack downloads were verified against publisher SHA-512 metadata. Exact versions, URLs, sizes, asset counts, hashes and prepared-manifest identity are recorded in `benchmarks/overlay-real-packs-2026-10-15.json`. Sources: [Faithful](https://modrinth.com/resourcepack/faithful-32x/version/lDYpMiqk), [Default HD](https://modrinth.com/resourcepack/default-hd-128x/version/rErHu3BE), [FPBR](https://modrinth.com/resourcepack/fpbr/version/dynf82xk). FPBR targets older 1.21.9 snapshots; it is measured as a large real 128x archive over prepared 26.3 resources, without claiming visual/version compatibility. Default HD is the publisher's free demo. Downloaded pack contents are not committed.
## Synthetic coverage
The existing fixtures contain 8,192 vanilla textures (128 MiB), 2,048 overrides (32 MiB) and 32 merged language files; equivalent directory/ZIP payloads are incompressible bytes. Eleven median samples compare identical output outside timing:
| Fixture | Original | Cached cold | Hit |
| --- | ---: | ---: | ---: |
| Directory | 108.487 ms | 126.438 ms | 7.438 ms |
| Deflated ZIP, 32.45 MiB | 155.540 ms | 155.453 ms | 0.128 ms |
| Directory, four 8 MiB files | 0.115 ms | 0.271 ms | 0.076 ms |
Directory topology scans remain a cost: the larger directory fixture adds about 17% cold overhead and gains 14.6x on hits. Tiny cold overlays add about 0.16 ms. No overall startup gain is inferred from either table.
## Reproduce and validate
```sh
@@ -41,10 +38,9 @@ export CARGO_INCREMENTAL=0
export HORIZON_OVERLAY_BENCH_VANILLA=/path/to/prepared/26.3
export HORIZON_OVERLAY_BENCH_PACKS='["/path/to/Faithful.zip","/path/to/DefaultHD.zip","/path/to/FPBR.zip"]'
cargo test -p horizon-client --lib --profile fast packs::cache::tests::benchmark_real_resource_root -- --ignored --nocapture --test-threads=1
cargo test -p horizon-client --lib --profile fast packs::cache::tests::benchmark -- --ignored --nocapture --test-threads=1 --skip benchmark_real_resource_root
cargo test -p horizon-client --lib --profile fast packs:: -- --nocapture
cargo clippy -p horizon-client --lib --tests --profile fast -- -D warnings
cargo fmt --all -- --check
```
Thirteen focused tests pass, covering source edits/replacements, Unix preserved-mtime edits, pack order/removal, overlays/filters, vanilla membership, marker/output-root recovery, failed ZIP rebuilds, symlink aliases/cycles, contention and unchanged relative link targets. All three opt-in benchmarks pass; strict Clippy, formatting and whitespace checks pass. Each overlay retains a small marker and empty lock file; cache hits retain no archive byte buffer.
Thirteen focused tests pass, covering source edits/replacements, Unix preserved-mtime edits, pack order/removal, overlays/filters, vanilla membership, marker/output-root recovery, failed ZIP rebuilds, symlink aliases/cycles, contention and unchanged relative link targets. The opt-in real-pack benchmark passes; strict Clippy, formatting and whitespace checks pass. Each overlay retains a small marker and empty lock file; cache hits retain no archive byte buffer.