| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent c8ee26c commit f3af361
1 file changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -113,11 +113,12 @@ custom storage/environment, global Git options, and unhandled command options | |||
| 113 | 113 | also retain their CLI contracts. A broken installed extension is reported as | |
| 114 | 114 | an import error; only an absent top-level `gix` selects CLI mode. | |
| 115 | 115 | ||
| 116 | - ## Future performance work | ||
| 116 | + ## Performance work | ||
| 117 | 117 | ||
| 118 | - These runtime and fixture optimizations have not been implemented. The local | ||
| 119 | - measurements use official GixPython 0.1.0 and existing CPython 3.12.14 on macOS | ||
| 120 | - arm64 at `89c609cf92335e75652d7725682e215a9ea080e5`. | ||
| 118 | + Native repository reuse remains future work. The fixture optimizations below | ||
| 119 | + are implemented as separate commits, each validated with GixPython before CLI. | ||
| 120 | + The original local measurements use official GixPython 0.1.0 and existing | ||
| 121 | + CPython 3.12.14 on macOS arm64 at `89c609cf92335e75652d7725682e215a9ea080e5`. | ||
| 121 | 122 | ||
| 122 | 123 | The full suite with coverage took 757.85 seconds wall-clock (757.04 seconds | |
| 123 | 124 | reported by pytest): 1,649 tests and 38 subtests passed, 79 skipped, and one | |
@@ -140,57 +141,85 @@ Consider retaining native repository/object-store state per `git.Repo`, with | |||
| 140 | 141 | explicit ownership, `close()` behavior, thread semantics, and invalidation for | |
| 141 | 142 | CLI/native mutations, configuration changes, and environment overrides. | |
| 142 | 143 | Preserve the current safety checks and diagnostics. Establish those contracts | |
| 143 | - before replacing the fresh-open policy below. | ||
| 144 | + before replacing the current fresh-open policy. | ||
| 144 | 145 | ||
| 145 | - ### Reuse prepared test fixtures | ||
| 146 | + ### Reuse prepared test fixtures (implemented) | ||
| 146 | 147 | ||
| 147 | 148 | A 19-case submodule rejection sample without coverage took 15.62 seconds: | |
| 148 | 149 | 1,258 `Git.execute()` calls accounted for 11.86 seconds, while 1,995 native | |
| 149 | 150 | repository-open/validation attempts accounted for 0.84 seconds. Most work was | |
| 150 | 151 | fixture setup. This sample supports prioritizing repeated setup subprocesses; | |
| 151 | 152 | it is not a profile of the entire suite. | |
| 152 | 153 | ||
| 153 | - Collection found 1,729 parameterized cases from 703 distinct source bodies. | ||
| 154 | + The original collection found 1,729 parameterized cases from 703 distinct source bodies. | ||
| 154 | 155 | Source inspection identified the following conservative set of 422 cases whose | |
| 155 | 156 | assertions do not require changing repository state after preparation. The | |
| 156 | 157 | remaining cases have not been exhaustively classified; these are reuse | |
| 157 | 158 | candidates, not proof that a shared fixture is safe in every execution order. | |
| 158 | 159 | ||
| 159 | - | Cases | Current setup | Future opportunity | | ||
| 160 | + | Original cases | Repeated setup | Implemented change | | ||
| 160 | 161 | | --- | --- | --- | | |
| 161 | - | 166 | `TExc` (157) and `TestActor` (9) inherit repository-building `TestBase`. | Use a base without repository setup; these assertions need no repository. | | ||
| 162 | - | 182 | Three submodule rejection bodies repeatedly build `movable_submodule`, then check snapshots for no mutation. | Share one committed baseline, with fresh Python wrappers and per-case temporary paths. | | ||
| 163 | - | 51 | Six submodule rejection bodies prepare nested metadata, separate metadata, intermediate/leaf symlinks, or retained metadata before checking rejection. | Prepare immutable variants once; group by layout rather than repeating setup for every operation or spelling. | | ||
| 164 | - | 15 | Eight revision-query bodies rebuild the same four-commit graph, refs, index, and reflogs through `rev_parse_repo`. | Share the prepared graph; keep the five mutating cases isolated. | | ||
| 165 | - | 8 | Tree lookup bodies clone and check out `0.3.2.1` through `with_rw_repo`. | Share one prepared historical repository; the assertions only read trees. | | ||
| 166 | - | ||
| 167 | - Thus at least 256 repository-using cases are initial sharing candidates, | ||
| 168 | - alongside 166 cases where repository setup could disappear. They could | ||
| 169 | - plausibly use about 14 prepared scenarios: one ordinary submodule baseline, | ||
| 170 | - 11 rejection-layout variants, one revision graph and one historical tree | ||
| 171 | - baseline. That scenario count is an implementation estimate, not validated | ||
| 172 | - fixture sharing. The full | ||
| 173 | - `movable_submodule` fixture is constructed for 322 cases and `local_submodule` | ||
| 174 | - for 68 cases. Even mutating cases could start from prepared filesystem copies, | ||
| 175 | - with writable refs, index, config, worktree and submodule metadata isolated; | ||
| 176 | - their shared object data and source repositories must remain immutable. | ||
| 177 | - Snapshot/copy cost and path relocation need measurement before choosing a | ||
| 178 | - strategy. Do not hard-link mutable Git metadata or rely on resetting only | ||
| 179 | - `HEAD` to restore a fixture. | ||
| 180 | - | ||
| 181 | - Additionally, all 25 collected `TestBase` classes reconstruct both historical | ||
| 182 | - dependency repositories, including checkouts and `git gc`: 50 constructions. | ||
| 183 | - Only four classes call the dependency-source helpers. Lazily preparing two | ||
| 184 | - immutable sources once per session could remove 48 of those constructions, | ||
| 185 | - independently of whether the consuming tests mutate their own repositories. | ||
| 186 | - | ||
| 187 | - Before widening fixture scope, verify that each candidate preserves refs, | ||
| 188 | - reflogs, index, configuration, worktree, metadata and source state; distinguish | ||
| 189 | - harmless cache changes from persistent changes. Keep mutable Python wrappers, | ||
| 190 | - environment patches and temporary paths isolated. Security rejection tests | ||
| 191 | - must retain their no-side-effect assertions and pristine starting state, so | ||
| 192 | - an earlier failure cannot contaminate later results. Profile setup/call/teardown | ||
| 193 | - and compare warmed runs before claiming a suite-wide improvement. | ||
| 162 | + | 166 | `TExc` (157) and `TestActor` (9) inherit repository-building `TestBase`. | Use the existing `TestCase` base without repository setup. | | ||
| 163 | + | 182 | Three submodule rejection bodies repeatedly build `movable_submodule`, then check snapshots for no mutation. | Prepare logical-name baselines once and copy the parent per case, retaining fresh wrappers and independent writable files. | | ||
| 164 | + | 51 | Six submodule rejection bodies prepare nested metadata, separate metadata, intermediate/leaf symlinks, or retained metadata before checking rejection. | Cache ten prepared layouts and restore complete copies at their original paths, preserving absolute Git links and symlinks. Cleanup removes the active copy even after failure. | | ||
| 165 | + | 15 | Eight revision-query bodies rebuild the same four-commit graph, refs, index, and reflogs through `rev_parse_repo`. | Prepare the graph once and copy it for every consumer, including mutating cases; recreate repository, branch and commit wrappers. | | ||
| 166 | + | 8 | Tree lookup bodies clone and check out `0.3.2.1` through `with_rw_repo`. | Read the historical tree directly through the existing class repository, removing clones and checkouts. | | ||
| 167 | + | ||
| 168 | + The `movable_submodule` baseline also serves mutating cases: all writable | ||
| 169 | + refs, index, config, objects, worktree and module metadata are filesystem copies, | ||
| 170 | + while the local clone source remains shared and immutable. The original 322 | ||
| 171 | + consumers no longer repeat repository initialization and submodule cloning. | ||
| 172 | + The original 68 `local_submodule` cases copy both source and parent from one | ||
| 173 | + prepared two-commit layout because these tests also mutate the source. The | ||
| 174 | + fixture relocates all source URLs and records the private URL in parent history | ||
| 175 | + for `RootModule` comparisons. No mutable Git metadata is hard-linked. | ||
| 176 | + | ||
| 177 | + Historical dependency sources are now lazy session fixtures. Originally all | ||
| 178 | + 25 `TestBase` classes reconstructed both sources (50 builds), although only four | ||
| 179 | + classes called the URL helpers. The suite now prepares each needed source once, | ||
| 180 | + with consuming tests retaining independent writable clones. | ||
| 181 | + | ||
| 182 | + Four additional checks exercise isolation: edits and refs in movable copies, | ||
| 183 | + restoration after deliberate mutation with an absolute symlink, private source | ||
| 184 | + commits, and revision-graph changes. Existing security no-side-effect snapshots | ||
| 185 | + remain in place. Native repository ownership, invalidation and thread semantics | ||
| 186 | + remain deferred as described above. | ||
| 187 | + | ||
| 188 | + Per-change affected tests on existing CPython 3.12.14/macOS arm64 with official | ||
| 189 | + GixPython 0.1.0, without coverage (wall-clock seconds including runner setup): | ||
| 190 | + | ||
| 191 | + | Change | Passed cases | GixPython first | CLI second | | ||
| 192 | + | --- | --- | --- | --- | | ||
| 193 | + | Repository-free actor/exception tests | 166 | 0.47 s | 0.49 s | | ||
| 194 | + | Lazy historical sources, all consumers | 206, plus 14 subtests; 6 skipped, 1 xfailed | 90.89 s | 160.82 s | | ||
| 195 | + | Movable baseline, top-level submodule tests | 333 | 88.63 s | 178.75 s | | ||
| 196 | + | Prepared rejection variants | 51 | 12.34 s | 26.23 s | | ||
| 197 | + | Layout restoration check | 1 | 1.33 s | 1.62 s | | ||
| 198 | + | Prepared revision graph | 23 | 4.39 s | 7.57 s | | ||
| 199 | + | Historical tree lookups, whole tree module | 22 | 1.66 s | 3.86 s | | ||
| 200 | + | Prepared no-fetch source and parent | 69 | 56.27 s | 117.52 s | | ||
| 201 | + | ||
| 202 | + These selections overlap, and their timings are validation records rather than | ||
| 203 | + isolated before/after benchmarks. The full-suite measurements below provide the | ||
| 204 | + broader comparison. Only the existing interpreter was used. | ||
| 205 | + | ||
| 206 | + At `c8ee26c7da373e28cc7ede17ef2eaadd763fcdfc`, the full GixPython suite | ||
| 207 | + with coverage passed in **404.61 seconds wall-clock (6m45s)**, with pytest | ||
| 208 | + reporting 404.12 seconds: 1,653 passed, 79 skipped, one expected failure, | ||
| 209 | + and 38 subtests passed. Coverage remains 90%. Compared with the original | ||
| 210 | + 757.85-second run, this saved 353.24 seconds (46.6%, about 1.87 times faster). | ||
| 211 | + This is one local before/after run per revision, not a statistical benchmark. | ||
| 212 | + | ||
| 213 | + The same operation counters now record 102,581 native operations and 21,402 | ||
| 214 | + CLI fallback decisions, down from 114,800 and 39,002 respectively. Raw Git | ||
| 215 | + calls and child processes remain outside those counters. | ||
| 216 | + | ||
| 217 | + The subsequent full CLI run with coverage passed in **755.78 seconds | ||
| 218 | + wall-clock (12m36s)**, with pytest reporting 755.30 seconds: 1,617 passed, | ||
| 219 | + 80 skipped, one expected failure, and 38 subtests passed. CLI coverage is 82%; | ||
| 220 | + backend-specific tests account for different collection and coverage. This CLI | ||
| 221 | + run validates the optimized suite; there is no matching pre-change CLI full-run | ||
| 222 | + measurement here. Repository-wide Ruff lint/format, mypy and pyright passed. | ||
| 194 | 223 | ||
| 195 | 224 | ## GixPython / Gitoxide follow-up ledger | |
| 196 | 225 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments