Files
RustNotMC/benchmarks/model-state-parse-2026-10-14.md
SashegDev 874b6f20c2 Клиент: начальный импорт кодовой базы
Основа — Horizon (MIT). История апстрима не переносится: этот репозиторий ведёт свою.
2026-10-29 22:04:28 +03:00

3.6 KiB

Reuse parsed model states

models::prepare parsed model-states.json to select blocks, then StateModels::load reopened and parsed the same document for binding and baking. StateModels::from_facts now borrows the first parsed map. The public load entry point still reads, parses and validates its own document. Both paths retain the fs::read + serde_json::from_slice strategy merged in PR #205.

The shared map uses BTreeMap, preserving the original catalog loader's JSON validation, including rejection of top-level null. The old selection map was serde_json::Map, also backed by a BTreeMap with the project's current features. Catalog binding, model selection and baking are unchanged. Preparation no longer holds a second complete JSON tree while constructing the catalog; no persistent cache or extra clones were added.

Measurement

The committed model_states_bench example runs main's two-parse sequence after PR #205 (first a serde JSON map, then StateModels::load) and the new one-parse sequence (first a BTreeMap, then StateModels::from_facts). Both select blocks from the same generated document with slice parsing and call the actual catalog binding/baking code. Timing includes file reads, parsing, filtering, binding, baking and result destruction. Fixture generation and equality checks run outside the timed region.

Prepared Minecraft resources were unavailable locally, so this is a synthetic 2,836,696-byte document containing 843 block schemas and 53,952 states. Schemas combine integer and named properties. Blockstate resources use weighted and conditional multipart choices with rotations and UV locking, sharing one model with a baked face. Its absent texture uses the normal missing-sprite fallback. Both paths read identical files with a warm OS cache. The workload does not represent the full diversity of production model and texture assets.

On AMD Ryzen 5 5600X, Linux 7.2.8-zen1-2-zen x86_64, rustc 1.99.0 (b940084d7 2026-09-28), Cargo fast profile, serial execution:

Path Median (15 samples)
Before: parse twice, with #205 slice readers 96.080 ms
After: reuse first parse, with #205 slice readers 73.585 ms

1.306x speedup; 23.41% less elapsed time for this loading segment after PR #205. Each path has two warmups, sample order alternates, and inputs/results use black_box. This excludes gallery placements, GPU work and overall application startup.

These measurements supersede the original unbuffered-reader timings (2732.004 ms → 1386.060 ms, 1.971x) after rebasing onto main at e96e1571. The reviewer measured approximately 1.05x with real prepared resources; the generated fixture's balance of parsing and binding differs from production. The change still removes one complete document read, parse and JSON tree.

Equality validation compares every state's selected variants and baked geometry at three positions, plus sprite layers and opacity/translucency flags. The focused test also checks matching schema/registry errors, malformed/missing source files, rejection of null, and successful shared-facts loading after the source file has been deleted.

Reproduce

export CARGO_TARGET_DIR=/home/bob/Documents/horizon/target
export CARGO_INCREMENTAL=0
cargo run -p horizon-client --profile fast --example model_states_bench -- 15
cargo test -p horizon-client --profile fast --example model_states_bench
cargo clippy -p horizon-client --all-targets --profile fast -- -D warnings
cargo fmt --all -- --check

The target directory can be changed for another machine. The example creates and removes its fixtures in the system temporary directory.