Skip to content

Commit d2e788a

Browse files
codexByron
authored andcommitted
test(perf): track newly native repository reads in CI benchmarks
Extend the existing `pyperf` journey with submodule inventory, tree/index revision paths and modes, and raw commit/tree readback. These use fresh public wrappers on the retained `Repo` and automatically join the existing separate benchmark CI job, result parity checks and per-measurement reporting. Read existing object bytes rather than invoking serializers: the fixed fixture has a signed commit, and benchmarking must not rewrite repository objects. Add a zero-CLI ceiling for each new measurement while retaining every existing ceiling. The journey still permits only its single patch-diff fallback launch. This measurement-only commit reduces backend CLI launches by 0. Its warm preflight records CLI/Gix counts of 11/0 for submodule inventory, 8/0 for revision paths and 1/0 for object readback. The complete expanded journey is 43/1. The preceding optimization commits implement these native reductions; this change keeps them visible and enforceable as coverage grows. Validation: Gix preflight passed all 14 ceilings and five comparison tests, then the CLI preflight and five tests passed. All 14 result digests matched. Repository-wide Ruff lint/format, mypy, basedpyright and `git diff --check` passed. Timed measurements will be recorded separately after final validation.
1 parent 0f08263 commit d2e788a

4 files changed

Lines changed: 34 additions & 2 deletions

File tree

‎doc/gix-backend.md‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,19 @@ environment metadata.
186186
### Existing-repository benchmark
187187

188188
[`test/performance/README.md`](../test/performance/README.md) describes the
189-
`pyperf` harness and fixed GitPython 3.1.45 fixture. It measures eight public-API
189+
`pyperf` harness and fixed GitPython 3.1.45 fixture. It measures eleven public-API
190190
operations and their complete journey on one already-open `git.Repo`, plus
191191
separate direct opening and discovery from `git/objects`. Fresh high-level
192192
wrappers preserve the cost of actual operations; imports, fixture preparation
193193
and parity preflight are outside timing. Native repository refresh remains
194194
inside operation timing, so these measurements include the cost of keeping
195195
retained state current.
196196

197+
Submodule inventory, revision path/mode lookup and raw commit/tree readback
198+
extend the already-open journey, each with a zero-CLI ceiling. The readback
199+
measurement reads existing bytes, including the signed fixture commit, without
200+
rewriting objects. Historical tables below retain their original workloads.
201+
197202
At `244e418da6cc43de129cbe2908d11be4c5ad457a`, using official GixPython
198203
0.1.0 and the same existing CPython 3.12.14/macOS arm64 interpreter for both
199204
installations, with Git 2.54.0 (Apple Git-157), six worker processes with three values each produced the

‎test/performance/README.md‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Backend benchmark
22

33
`bench_repository.py` uses `pyperf` to measure a complete read-only journey and
4-
eight named operations against an existing repository, plus separate direct
4+
eleven named operations against an existing repository, plus separate direct
55
opening and nested-directory discovery measurements. It keeps one `Repo`
66
instance open per worker, but creates fresh commit/tree/index wrappers per
77
invocation so their cached properties cannot turn the measurement into a no-op.
@@ -72,6 +72,12 @@ at least one parent, a root `README.md` and a `git/objects` directory for the
7272
nested discovery measurement. The harness never prepares or
7373
mutates that worktree, and ignores ambient Git environment/config overrides.
7474

75+
The journey also enumerates submodules, resolves tree/index revisions with
76+
their paths and modes, and reads raw commit/tree bytes through the object
77+
database. The last operation covers serialization readback without rewriting
78+
objects; the pinned fixture's signed commit remains intact. These three
79+
measurements have zero-CLI ceilings and join the existing CI job automatically.
80+
7581
Add a function returning JSON-compatible results to `MEASUREMENTS` in
7682
`bench_repository.py`. It automatically becomes a separate benchmark and part
7783
of the journey and parity checks. Include supported and fallback operations;

‎test/performance/bench_repository.py‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,21 @@ def index(repo):
4444
return sorted([path, stage, entry.mode, entry.hexsha] for (path, stage), entry in repo.index.entries.items())
4545

4646

47+
def submodules(repo):
48+
return [[module.name, module.path, module.hexsha, module.url, module.branch_path] for module in repo.submodules]
49+
50+
51+
def revision_paths(repo):
52+
objects = [repo.rev_parse(revision) for revision in ("HEAD:README.md", "HEAD:git", ":README.md")]
53+
return [[obj.hexsha, obj.path, obj.mode] for obj in objects]
54+
55+
56+
def object_readback(repo):
57+
commit = repo.commit("HEAD")
58+
# Read the same bytes used by serialization, without writing objects or stripping signatures.
59+
return [sha256(obj.data_stream.read()).hexdigest() for obj in (commit, commit.tree)]
60+
61+
4762
def graph(repo):
4863
tip, parent = repo.commit("HEAD"), repo.commit("HEAD~1")
4964
return {
@@ -81,6 +96,9 @@ def worktree(repo):
8196
"history_25": history,
8297
"browse_tree_and_blob": browse,
8398
"read_index": index,
99+
"submodule_inventory": submodules,
100+
"revision_paths": revision_paths,
101+
"object_readback": object_readback,
84102
"revision_graph": graph,
85103
"diff_and_stats": changes,
86104
"patch_diff": patch,

‎test/performance/cli-budget.json‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
"history_25": 0,
77
"browse_tree_and_blob": 0,
88
"read_index": 0,
9+
"submodule_inventory": 0,
10+
"revision_paths": 0,
11+
"object_readback": 0,
912
"revision_graph": 0,
1013
"diff_and_stats": 0,
1114
"patch_diff": 1,

0 commit comments

Comments
 (0)