# Pinned cross-runtime performance evidence This directory compares representative offline work in native Rust with the pinned C# source at commit `2aa70bb68513b39795da5d13c88f31b86e85a3ba`. The runners are separate executables. The Rust executable never starts a CLR, loads a managed assembly, accesses a grid, or reads `.env`. ## Workloads and fixtures `fixtures/manifest.json` records SHA-256 for every shared input. Both runners refuse a changed fixture. The suite measures UUID/matrix/quaternion operations, all five supported LLSD codecs, packet encode/decode, notecard/TGA/mesh decode, inventory and object updates, simple rendering, and a batched offline client message pipeline. Each report contains one cold operation and seven warm samples. It records latency, throughput, allocated bytes, retained heap bytes, and allocation count where the runtime exposes it. .NET reports a null allocation count because its supported in-process GC API exposes bytes, not operation count; it does not substitute a misleading zero. The checked-in inputs are deliberately modest so the suite completes on a four-core, 8 GiB release worker. Iteration counts live in `workloads.json`. Regenerate binary inputs only after an intentional fixture review: ```sh cargo run -p metacrate-performance --profile benchmark -- \ fixtures --fixture-root benchmarks/fixtures ``` ## Reproducing the reports Use the same otherwise-idle machine for both runs. Disable adaptive power or thermal throttling where the host permits it. The committed evidence was captured on Linux x86-64 with four AMD EPYC-Genoa vCPUs and 7.6 GiB RAM, Rust 1.97.1, .NET SDK 10.0.400, and the .NET 8.0.30 runtime. C# is built in Release for `net8.0`. Rust uses the repository's `benchmark` profile (opt-level 1, debug/incremental disabled): higher optimization of the generated core exceeds the memory limit on this release worker, so this is a conservative Rust result. ```sh REFERENCE_ROOT=/absolute/path/to/libremetaverse test "$(git -C "$REFERENCE_ROOT" rev-parse HEAD)" = \ 2aa70bb68513b39795da5d13c88f31b86e85a3ba dotnet build benchmarks/csharp-reference/MetaCrate.ReferenceBenchmarks.csproj \ -c Release -p:ReferenceRoot="$REFERENCE_ROOT" dotnet benchmarks/csharp-reference/bin/Release/net8.0/MetaCrate.ReferenceBenchmarks.dll \ run --reference-root "$REFERENCE_ROOT" \ --fixture-root benchmarks/fixtures \ --output benchmarks/results/csharp-linux-x86_64.json cargo run -p metacrate-performance --profile benchmark -- \ run --fixture-root benchmarks/fixtures \ --output benchmarks/results/rust-linux-x86_64.json cargo run -p metacrate-performance --profile benchmark -- \ compare --rust benchmarks/results/rust-linux-x86_64.json \ --reference benchmarks/results/csharp-linux-x86_64.json \ --output benchmarks/results/comparison.json cargo run -p metacrate-performance --profile benchmark -- \ audit --fixture-root benchmarks/fixtures \ --rust benchmarks/results/rust-linux-x86_64.json \ --reference benchmarks/results/csharp-linux-x86_64.json \ --comparison benchmarks/results/comparison.json ``` The C# runner executes `git rev-parse` itself and rejects any other source commit. The comparison rejects different fixture hashes, operating systems, or architectures. ## Release criteria and reviewed differences `release-criteria.json` is executable policy. A warm median at least 25% slower than the reference is material and must be reviewed; the hard default is no more than 2.0x latency or allocated bytes. Reference operations below one microsecond are latency-noise exempt, but not allocation exempt. Three workload-specific differences are accepted: - Rust LLSD JSON owns and validates the bounded decoded tree. It is over four times faster in this evidence, so up to 2.1x allocated bytes is accepted. - Rust rendering performs the completed behavior: six faces, 24 vertices, 36 indices, checked normals, UVs, extents, and materials. The pinned C# `SimpleRenderer` still returns a one-face/eight-vertex placeholder cube. Slowing Rust down by removing correctness would violate the milestone, so the policy accepts up to 8x latency and 4x allocated bytes for this workload. - Rust client throughput returns checked `Result` values and owns the bounded OSD map throughout the message pipeline. It allocates fewer bytes than C#; its measured 1.64x latency is reviewed up to the unchanged 2x hard limit. No exception permits changed wire data, decoded values, fixture output, or public behavior. Any other threshold failure blocks the audit.