Thread (8 messages) 8 messages, 2 authors, 2h ago
HOTtoday

[PATCH 0/4] last-modified: use the pathspec's Bloom key to pre-filter commits

From: Toon Claes <hidden>
Date: 2026-07-17 15:47:08

We have received a report[1] git-last-modified(1) is slow compared to
git-log(1) if you want to find the last commit for all entries in a
directory. For example running the following command on ziglang/zig[2]:

   $ git last-modified -t --max-depth=0 $OID -- doc/langref/

Turns out to find results about 2.5 times slower than:

   $ git log --name-status -c --format=commit%x00%H %P%x00" \
       --parents --no-renames -t -z $OID -- :(literal)doc/langref

Now the latter needs some post-processing to come to the same results,
the total solution still is faster than integrating
git-last-modified(1).

After some research we've discovered the Bloom filters aren't used
optimally. But it turns out the code powering git-log(1) can fairly easy
be reused. We do this in a few steps:

 - Patch 1 moves a condition around so it becomes deduplicated and
   eventually can be reused by git-last-modified(1).
 - Patch 2 exposes a helper from revision.c publicly. The function is
   split out so the Bloom filter wouldn't be looked up twice from
   git-last-modified(1).
 - Patch 3 uses this new helper in git-last-modified(1).
 - Patch 4 is bonus change, which optimizes when working with wildcard
   pathspecs.

Below are benchmark on the ziglang/zig repository for the `doc/langref/`
directory (with commit-graphs writting using `--changed-paths`):

    Benchmark 1: master last-modified
      Time (mean ± σ):      52.6 ms ±   4.0 ms    [User: 49.2 ms, System: 3.0 ms]
      Range (min … max):    48.2 ms …  73.8 ms    62 runs

    Benchmark 2: HEAD last-modified
      Time (mean ± σ):      14.3 ms ±   1.8 ms    [User: 12.0 ms, System: 2.1 ms]
      Range (min … max):    10.5 ms …  18.9 ms    182 runs

    Benchmark 3: git log
      Time (mean ± σ):      17.4 ms ±   1.4 ms    [User: 13.5 ms, System: 3.7 ms]
      Range (min … max):    15.0 ms …  26.1 ms    185 runs

    Summary
      HEAD last-modified ran
        1.22 ± 0.18 times faster than git log
        3.66 ± 0.55 times faster than master last-modified

Similar timings are seen across a few other repositories (like GitLab's
monolith gitlab-org/gitlab)

[1]: https://lore.kernel.org/git/17f356ff-7bfb-47f5-b714-62a95cc8b821@codeberg.org/ (local)
[2]: https://codeberg.org/ziglang/zig

---
Toon Claes (4):
      revision: move bloom keyvec precondition into function
      revision: expose check for paths maybe changed in Bloom filter
      last-modified: check pathspec against Bloom filter first
      last-modified: keep per-path Bloom filters for wildcard pathspecs

 builtin/last-modified.c | 11 +++++++++++
 revision.c              | 32 +++++++++++++++++++++++---------
 revision.h              | 17 +++++++++++++++++
 3 files changed, 51 insertions(+), 9 deletions(-)



---
base-commit: 55526a18268bbc1ddaf8a6b7850c33d984eac9e9
change-id: 20260716-toon-speed-up-last-modified-b04ea1f21831
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help