On Wed, Aug 21, 2019 at 07:35:15PM +0200, SZEDER Gábor wrote:
> So line-level log clearly computes a lot less diffs than
> '--full-history', though still about 50% more than a regular
> pathspec-limited history traversal.  Looking at the commit-parent
> pairs in the output, it appears that the difference comes mostly from
> merge commits, because line-level log compares a merge commit with all
> of its parents.

> It seems there is still more room for improvements by avoiding
> commit-non_first_parent diffs when the first parent is TREESAME, and
> doing so could hopefully avoid triggering rename detection in those
> subtree merges or in case of your evil path.

Well, that fruit hung much lower than I though, just look at the size
of the WIP patch below.  I just hope that there are no unexpected
surprises, but FWIW it produces the exact same output for all files up
to 't/t5515' in v2.23.0 as the previous patch.

Can't wait to see how it fares with that evil Windows path :)

  --- >8 ---

Subject: [PATCH 3/2] WIP line-log: stop diff-ing after first TREESAME merge 
parent

  # git.git, ~25% of all commits are merges
  $ time git --no-pager log -L:read_alternate_refs:sha1-file.c v2.23.0

  Before:

    real    0m2.516s
    user    0m2.456s
    sys     0m0.060s

  After:

    real    0m1.132s
    user    0m1.096s
    sys     0m0.036s

  # linux.git, ~7% of all commits are merges
  $ time ~/src/git/git --no-pager log \
    -L:build_restore_work_registers:arch/mips/mm/tlbex.c v5.2

  Before:

    real    0m2.599s
    user    0m2.466s
    sys     0m0.157s

  After:

    real    0m1.976s
    user    0m1.856s
    sys     0m0.121s

[TODO: get rid of unnecessary arrays, tests?, write commit message...]
---
 line-log.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/line-log.c b/line-log.c
index 9010e00950..a4b032f83a 100644
--- a/line-log.c
+++ b/line-log.c
@@ -1184,13 +1184,11 @@ static int process_ranges_merge_commit(struct rev_info 
*rev, struct commit *comm
 
        p = commit->parents;
        for (i = 0; i < nparents; i++) {
+               int changed;
                parents[i] = p->item;
                p = p->next;
                queue_diffs(range, &rev->diffopt, &diffqueues[i], commit, 
parents[i]);
-       }
 
-       for (i = 0; i < nparents; i++) {
-               int changed;
                cand[i] = NULL;
                changed = process_all_files(&cand[i], rev, &diffqueues[i], 
range);
                if (!changed) {
@@ -1203,7 +1201,7 @@ static int process_ranges_merge_commit(struct rev_info 
*rev, struct commit *comm
                        commit_list_append(parents[i], &commit->parents);
                        free(parents);
                        free(cand);
-                       free_diffqueues(nparents, diffqueues);
+                       free_diffqueues(i, diffqueues);
                        /* NEEDSWORK leaking like a sieve */
                        return 0;
                }
-- 
2.23.0.352.gebb2b55eae

Reply via email to