Skip to content

Fix performance regression in v2.55 related to having many packfiles - #971

Merged
dscho merged 1 commit into
vfs-2.55.0from
fix-perf-regression-in-v2.55
Aug 5, 2026
Merged

Fix performance regression in v2.55 related to having many packfiles#971
dscho merged 1 commit into
vfs-2.55.0from
fix-perf-regression-in-v2.55

Conversation

@dscho

@dscho dscho commented Aug 4, 2026

Copy link
Copy Markdown
Member

When there are many packfiles in the repository (or in an alternate of it), a regression introduced into Git v2.53 introduced complexity quadratic in the number of the packfiles. In one instance, causing a slow-down of a simple git rev-parse --short HEAD (as used in GIT_PS1) from 0.4s to 4.5s. Let's fix that by avoiding the quadratic behavior in the most common case: loading the packfiles afresh.

In another (internally-reported) instance, clone times that increased to over 30 minutes were reported to reduce to under 2 minutes with this patch.

This closes #970.

@dscho
dscho force-pushed the fix-perf-regression-in-v2.55 branch from 0562289 to 70c8828 Compare August 4, 2026 23:12
@dscho
dscho marked this pull request as ready for review August 5, 2026 07:37
@dscho dscho self-assigned this Aug 5, 2026
@dscho
dscho requested review from mjcheetham and a lite review from Copilot August 5, 2026 07:41

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a performance regression when repositories contain very large numbers of packfiles by removing an O(n) “dedupe/removal” step from the hot path used while initially loading packfiles into a packfile_store. It also extends the perf suite to cover the rev-parse --short scenario that motivated the report.

Changes:

  • Add a fast-path helper to append a new pack entry to a packfile_list without scanning/removing.
  • Use that helper when adding packs to a packfile_store, avoiding quadratic behavior during bulk pack discovery/loading.
  • Add a perf test that measures git rev-parse --short HEAD with 10,000 packs.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
t/perf/p5303-many-packs.sh Adds a perf benchmark for rev-parse --short under extreme packfile counts.
packfile.c Introduces packfile_list_append_new() and uses it in packfile_store_add_pack() to avoid O(n²) pack insertion behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

mjcheetham
mjcheetham previously approved these changes Aug 5, 2026
Comment thread packfile.c Outdated
Since 589127c (packfile: move list of packs into the packfile
store, 2025-10-30), there is a performance regression when many
packfiles need to be loaded: `packfile_store_add_pack()` now calls
`packfile_list_remove_internal()` to detect whether the packfile was
_already_ in the list, if if so, move it to the end of the list. This
function linearly scans the existing list before every insertion. Newly
loading N packs therefore has complexity O(N²).

In one reported use case (#970),
N equals 37,815 and caused a slow-down of a simple `git rev-parse
--short HEAD` (which is regularly executed as part of `GIT_PS1`) from
0.4s to 4.5s. In another, heavily exercised CI scenario, clone times
increased from under 2 minutes to over half an hour.

Let's fix this by establishing a fast path for known-new packfiles.

The keen reader will note that there is currently only a single,
"known-new" caller of the `packfile_list_append()` function, and wonder
why not simply remove this check whether the packfile already exists in
the list? Originally, when above-mentioned commit introduced that logic,
there was a second caller in `prepare_midx()`, which would have required
that check, but that caller was removed in 6aff1f2 (packfile:
always add packfiles to MRU when adding a pack, 2025-10-30). Still, the
function is declared in a header file, and to avoid any problems with
in-flight or downstream callers, it is safer to extend the signature to
be explicit whether or not to skip that check.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@dscho
dscho force-pushed the fix-perf-regression-in-v2.55 branch from 70c8828 to 11f7294 Compare August 5, 2026 09:35
@dscho
dscho enabled auto-merge August 5, 2026 09:37
@dscho
dscho requested a review from mjcheetham August 5, 2026 09:37
@dscho
dscho merged commit 042625d into vfs-2.55.0 Aug 5, 2026
127 checks passed
@dscho
dscho deleted the fix-perf-regression-in-v2.55 branch August 5, 2026 10:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Performance regression between microsoft Git 2.52 and Microsoft git 2.55

3 participants