All of lore.kernel.org
 help / color / mirror / Atom feed
From: Toon Claes <toon@iotcl.com>
To: Gusted <gusted@codeberg.org>,
	git@vger.kernel.org, Jeff King <peff@peff.net>
Subject: Re: git-last-modified(1) slower than git-log(1)?
Date: Thu, 16 Jul 2026 11:26:25 +0200	[thread overview]
Message-ID: <87v7afffpa.fsf@emacs.iotcl.com> (raw)
In-Reply-To: <17f356ff-7bfb-47f5-b714-62a95cc8b821@codeberg.org>

Gusted <gusted@codeberg.org> writes:

> Hi,
>
> I'm working at switching Forgejo's implementation of getting the last
> modified commits in a directory to git-last-modified(1). I'd expected
> equal or better performance than the current implementation, but have
> not yet been able to get this and I'm a bit puzzled as to why.
>
> The current implementation of Forgejo (inherited from Gitea) works
> roughly like this:
> 1. Run `git log --name-status -c --format=commit%x00%H %P%x00" --parents
> --no-renames -t -z $OID -- :(literal)some/path`, the output of this is
> quite complex and possible outputs more information than necessary.
> 2. The output of this is piped to some code to a parser and reconstructs
> what commit ID last modified each file in the directory.
> 3. Via `git cat-file --batch` get each unique commits information.
>
> With git-last-modified(1) (-z --show-trees --max-depth=0) this replaces
> step 1-2, but is slower. I've isolated the degraded performance to the
> fact that git-last-changed(1) takes more time to finish. So from my
> perspective it does not seem worth it to replace the current
> implementation with git-last-modified(1), and I would like to know if
> I'm missing something here or if git-last-modified(1) possibly could see
> a speedup?
>
> The repository I'm currently using to evaluate the performance is
> https://codeberg.org/ziglang/zig
>
> Reproduction steps:
> 1. `git clone https://codeberg.org/ziglang/zig $(mktemp -d)`
> 2. cd to tmp directory.
> 3. `git commit-graph write --changed-paths`. As git-last-modified(1)
> makes good use of the bloom filters.
> 4. `hyperfine 'git last-modified -z -t --max-depth=0
> 80d06578ac66bce3aa0a21e9610cdb782b9a0593 -- doc/langref/' 'git log
> --name-status -c "--format=commit%x00%H %P%x00" --parents --no-renames
> -t -z 80d06578ac66bce3aa0a21e9610cdb782b9a0593 -- ":(literal)doc/langref"'`
>
> With as output:
> Benchmark 1: git last-modified -z -t --max-depth=0
> 80d06578ac66bce3aa0a21e9610cdb782b9a0593 -- doc/langref/
>  Time (mean ± σ): 66.5 ms ± 0.6 ms [User: 60.6 ms, System: 5.2 ms]
>  Range (min … max): 65.3 ms … 67.7 ms 44 runs
>
> Benchmark 2: git log --name-status -c "--format=commit%x00%H %P%x00"
> --parents --no-renames -t -z 80d06578ac66bce3aa0a21e9610cdb782b9a0593 --
> ":(literal)doc/langref"
>  Time (mean ± σ): 26.2 ms ± 1.0 ms [User: 17.3 ms, System: 8.4 ms]
>  Range (min … max): 24.3 ms … 30.1 ms 110 runs
>
> Summary
>  git log --name-status -c "--format=commit%x00%H %P%x00" --parents
> --no-renames -t -z 80d06578ac66bce3aa0a21e9610cdb782b9a0593 --
> ":(literal)doc/langref" ran
>  2.54 ± 0.10 times faster than git last-modified -z -t --max-depth=0
> 80d06578ac66bce3aa0a21e9610cdb782b9a0593 -- doc/langref/

Hi Gusted,

Thanks for reaching out.

You're actually not the first to notice this, and I've been aware of
this.

The thing is, you're testing the difference on a single file. For us at
GitLab, it wasn't very useful to optimize that use-case, because usually
we want to see the last commit for a bunch of files at once.
So the use-case for git-last-modified(1) for us has been to replace
(pseudo code):

$ FILES=$(git ls-tree $COMMIT $PATH)
$ foreach $FILE in $FILES; do git log -1 $COMMIT -- $FILE; end

GitLab is batching files 25 at once, and in my benchmarking, it was
shown git-last-modified(1) is faster:

$ git last-modified $COMMIT -- <files

(I did this benchmarking in our Gitaly component to have a real-world
experience and you can visit the results at:
https://gitlab.com/gitlab-org/gitaly/-/merge_requests/7999#note_2850505479
)

So we left the door open for future improvement, although I never have
gotten to it. At some point I was trying to chase down when git-log(1)
was doing differently, but I never figured it out.

But this email challenged me already. And with some help of AI, I
managed to work on some improvements. You can expect a patch series
soon.

(Right before sending out this mail I noticed Peff sent out some changes
as well. I'll coordinate how to combine.)

-- 
Cheers,
Toon

      parent reply	other threads:[~2026-07-16  9:26 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-14 18:33 git-last-modified(1) slower than git-log(1)? Gusted
2026-07-16  4:28 ` Jeff King
2026-07-16 11:42   ` Toon Claes
2026-07-16  9:26 ` Toon Claes [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87v7afffpa.fsf@emacs.iotcl.com \
    --to=toon@iotcl.com \
    --cc=git@vger.kernel.org \
    --cc=gusted@codeberg.org \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.