"""MPack performance benchmarks — prove parity with GitHub-class operations. All tests use LocalFileTransport (loopback — zero network overhead) so the measured time is pure protocol + I/O cost with no network latency. Targets ------- - 1 000-object push : < 3 s (GitHub does ~1 s over WAN for same size) - 1 000-commit clone : < 3 s - 500-object stream : < 1 s (writer + reader round-trip, no disk I/O) - zstd > zlib speed : compress 500 objects faster with zstd (when available) - Peak memory : bounded by 2 × largest single object during push """ from __future__ import annotations import datetime import hashlib import json import pathlib import time import pytest from muse.core.snapshot import compute_commit_id, compute_snapshot_id from muse.core.store import CommitRecord, SnapshotRecord, write_commit, write_snapshot from muse.core.object_store import write_object from muse.core._types import long_id _DT = datetime.datetime(2026, 1, 1, tzinfo=datetime.timezone.utc) def _sha(data: bytes) -> str: return long_id(hashlib.sha256(data).hexdigest()) def _init_repo(path: pathlib.Path) -> pathlib.Path: muse = path / ".muse" for d in ("commits", "snapshots", "objects", "refs/heads"): (muse / d).mkdir(parents=True, exist_ok=True) (muse / "HEAD").write_text("ref: refs/heads/main", encoding="utf-8") (muse / "repo.json").write_text( json.dumps({"repo_id": "perf-test", "domain": "code"}), encoding="utf-8", ) return path def _make_chain(root: pathlib.Path, n_commits: int, files_per_commit: int = 1) -> list[str]: """Create a linear commit chain; return all commit IDs tip-first.""" parent: str | None = None commit_ids: list[str] = [] for i in range(n_commits): manifest: dict[str, str] = {} for j in range(files_per_commit): content = f"# commit {i} file {j}\n".encode() * 20 oid = _sha(content) write_object(root, oid, content) manifest[f"f{i}_{j}.py"] = oid snap_id = compute_snapshot_id(manifest) write_snapshot(root, SnapshotRecord(snapshot_id=snap_id, manifest=manifest, created_at=_DT)) parent_ids = [parent] if parent else [] cid = compute_commit_id(parent_ids, snap_id, f"commit {i}", _DT.isoformat()) write_commit(root, CommitRecord( commit_id=cid, repo_id="perf-test", branch="main", snapshot_id=snap_id, message=f"commit {i}", committed_at=_DT, parent_commit_id=parent, )) commit_ids.append(cid) parent = cid ref = root / ".muse" / "refs" / "heads" / "main" ref.write_text(commit_ids[-1], encoding="utf-8") return commit_ids # --------------------------------------------------------------------------- # Stream writer/reader throughput # --------------------------------------------------------------------------- class TestStreamThroughput: def test_500_object_stream_under_1s(self) -> None: from muse.core.mpack import MPackStreamWriter, MPackStreamReader w = MPackStreamWriter() r = MPackStreamReader() n = 500 # Pre-build object data objects = [f"content of object {i}\n".encode() * 10 for i in range(n)] t0 = time.monotonic() body = w.write_header(op="push", branch="main", n_objects=n, n_commits=1) for raw in objects: body += w.write_object_raw( object_id=_sha(raw), raw_bytes=raw, compress="zlib", ) body += w.write_commit_pack(commits=[], snapshots=[]) body += w.write_end(n_objects=n, n_commits=1) r.feed(body) frames = list(r.frames()) elapsed = time.monotonic() - t0 assert len([f for f in frames if f["t"] == "O"]) == n assert elapsed < 1.0, f"500-object stream took {elapsed:.3f}s — target < 1s" def test_1000_object_stream_under_2s(self) -> None: from muse.core.mpack import MPackStreamWriter, MPackStreamReader w = MPackStreamWriter() r = MPackStreamReader() n = 1000 objects = [f"object data {i}\n".encode() * 15 for i in range(n)] t0 = time.monotonic() body = w.write_header(op="push", branch="main", n_objects=n, n_commits=1) for raw in objects: body += w.write_object_raw(object_id=_sha(raw), raw_bytes=raw) body += w.write_commit_pack(commits=[], snapshots=[]) body += w.write_end(n_objects=n, n_commits=1) r.feed(body) list(r.frames()) elapsed = time.monotonic() - t0 assert elapsed < 2.0, f"1000-object stream took {elapsed:.3f}s — target < 2s" # --------------------------------------------------------------------------- # build_mpack throughput # --------------------------------------------------------------------------- class TestBuildMpackThroughput: def test_100_commit_chain_build_under_2s(self, tmp_path: pathlib.Path) -> None: from muse.core.pack import build_mpack root = _init_repo(tmp_path) commit_ids = _make_chain(root, n_commits=100, files_per_commit=5) t0 = time.monotonic() bundle = build_mpack(root, [commit_ids[-1]]) elapsed = time.monotonic() - t0 assert len(bundle["commits"]) == 100 assert elapsed < 2.0, f"build_mpack(100 commits, 5 files each) took {elapsed:.3f}s" def test_build_and_apply_1000_objects_under_3s(self, tmp_path: pathlib.Path) -> None: from muse.core.pack import build_mpack, apply_mpack src = _init_repo(tmp_path / "src") dst = _init_repo(tmp_path / "dst") commit_ids = _make_chain(src, n_commits=50, files_per_commit=20) t0 = time.monotonic() bundle = build_mpack(src, [commit_ids[-1]]) apply_mpack(dst, bundle) elapsed = time.monotonic() - t0 assert elapsed < 3.0, ( f"build_mpack + apply_mpack (50 commits × 20 files) took {elapsed:.3f}s — target < 3s" ) # --------------------------------------------------------------------------- # Compression speed comparison # --------------------------------------------------------------------------- class TestCompressionSpeed: def test_zstd_not_slower_than_2x_zlib(self) -> None: from muse.core.compression import ZSTD_AVAILABLE, compress_zstd, compress_zlib if not ZSTD_AVAILABLE: pytest.skip("zstd not installed") data = b"source line\n" * 50_000 # ~600 KB t0 = time.monotonic() for _ in range(10): compress_zlib(data) zlib_time = time.monotonic() - t0 t0 = time.monotonic() for _ in range(10): compress_zstd(data) zstd_time = time.monotonic() - t0 assert zstd_time < zlib_time * 2.0, ( f"zstd ({zstd_time:.3f}s) > 2× zlib ({zlib_time:.3f}s) — expected faster" ) def test_zstd_ratio_on_source_code(self) -> None: from muse.core.compression import ZSTD_AVAILABLE, compress_zstd, compress_zlib if not ZSTD_AVAILABLE: pytest.skip("zstd not installed") data = b"def function(arg):\n return arg * 2\n" * 500 zstd_ratio = len(compress_zstd(data)) / len(data) zlib_ratio = len(compress_zlib(data)) / len(data) # zstd should compress at least as well as zlib assert zstd_ratio <= zlib_ratio * 1.15, ( f"zstd ratio {zstd_ratio:.2%} vs zlib {zlib_ratio:.2%} — zstd too large" ) # --------------------------------------------------------------------------- # apply_mpack throughput (clone simulation) # --------------------------------------------------------------------------- class TestApplyMpackThroughput: def test_clone_simulation_500_commits_under_3s(self, tmp_path: pathlib.Path) -> None: from muse.core.pack import build_mpack, apply_mpack src = _init_repo(tmp_path / "src") dst = _init_repo(tmp_path / "dst") commit_ids = _make_chain(src, n_commits=500, files_per_commit=2) bundle = build_mpack(src, [commit_ids[-1]]) t0 = time.monotonic() result = apply_mpack(dst, bundle) elapsed = time.monotonic() - t0 assert result["commits_written"] == 500 assert elapsed < 3.0, ( f"apply_mpack (500-commit clone) took {elapsed:.3f}s — target < 3s" )