]> git.ipfire.org Git - thirdparty/git.git/commit
commit: convert pop_most_recent_commit() to prio_queue
authorRené Scharfe <l.s.r@web.de>
Fri, 18 Jul 2025 09:39:06 +0000 (11:39 +0200)
committerJunio C Hamano <gitster@pobox.com>
Tue, 22 Jul 2025 14:28:23 +0000 (07:28 -0700)
commitd6ec08788e667d4f556e9c2d97bbd7adb7e582be
tree833bcbff1f6ebaf69daac4faabd4e23969f7b064
parent16bd9f20a403117f2e0d9bcda6c6e621d3763e77
commit: convert pop_most_recent_commit() to prio_queue

pop_most_recent_commit() calls commit_list_insert_by_date() for parent
commits, which is itself called in a loop.  This can lead to quadratic
complexity if there are many merges.  Replace the commit_list with a
prio_queue to ensure logarithmic worst case complexity and convert all
three users.

Add a performance test that exercises one of them using a pathological
history that consists of 50% merges and 50% root commits to demonstrate
the speedup:

Test                          v2.50.1           HEAD
----------------------------------------------------------------------
1501.2: rev-parse ':/65535'   2.48(2.47+0.00)   0.20(0.19+0.00) -91.9%

Alas, sane histories don't benefit from the conversion much, and
traversing Git's own history takes a 1% performance hit on my machine:

   $ hyperfine -w3 -L git ./git_2.50.1,./git '{git} rev-parse :/^Initial.revision'
   Benchmark 1: ./git_2.50.1 rev-parse :/^Initial.revision
     Time (mean ± σ):      1.071 s ±  0.004 s    [User: 1.052 s, System: 0.017 s]
     Range (min … max):    1.067 s …  1.078 s    10 runs

   Benchmark 2: ./git rev-parse :/^Initial.revision
     Time (mean ± σ):      1.079 s ±  0.003 s    [User: 1.060 s, System: 0.017 s]
     Range (min … max):    1.074 s …  1.083 s    10 runs

   Summary
     ./git_2.50.1 rev-parse :/^Initial.revision ran
       1.01 ± 0.00 times faster than ./git rev-parse :/^Initial.revision

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
commit.c
commit.h
fetch-pack.c
object-name.c
t/meson.build
t/perf/p1501-rev-parse-oneline.sh [new file with mode: 0755]
walker.c