Skip to content

Commit

Permalink
pickaxe -S: slightly optimize contains()
Browse files Browse the repository at this point in the history
When the "log -S<pat>" switch counts occurrences of <pat> on the
pre-image and post-image of a change. As soon as we know we had e.g. 1
before and 2 now we can stop, we don't need to keep counting past 2.

With this change a diff between A and B may have different performance
characteristics than between B and A. That's OK in this case, since
we'll emit the same output, and the effect is to make one of them
better.

I'm picking a check of "one" first on the assumption that it's a more
common case to have files grow over time than not.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
avar authored and gitster committed May 11, 2021
1 parent 5d35a95 commit 5b0672a
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions diffcore-pickaxe.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ static int diff_grep(mmfile_t *one, mmfile_t *two,
return ecbdata.hit;
}

static unsigned int contains(mmfile_t *mf, regex_t *regexp, kwset_t kws)
static unsigned int contains(mmfile_t *mf, regex_t *regexp, kwset_t kws,
unsigned int limit)
{
unsigned int cnt = 0;
unsigned long sz = mf->size;
Expand All @@ -88,6 +89,9 @@ static unsigned int contains(mmfile_t *mf, regex_t *regexp, kwset_t kws)
sz--;
}
cnt++;

if (limit && cnt == limit)
return cnt;
}

} else { /* Classic exact string match */
Expand All @@ -99,6 +103,9 @@ static unsigned int contains(mmfile_t *mf, regex_t *regexp, kwset_t kws)
sz -= offset + kwsm.size[0];
data += offset + kwsm.size[0];
cnt++;

if (limit && cnt == limit)
return cnt;
}
}
return cnt;
Expand All @@ -108,8 +115,8 @@ static int has_changes(mmfile_t *one, mmfile_t *two,
struct diff_options *o,
regex_t *regexp, kwset_t kws)
{
unsigned int c1 = one ? contains(one, regexp, kws) : 0;
unsigned int c2 = two ? contains(two, regexp, kws) : 0;
unsigned int c1 = one ? contains(one, regexp, kws, 0) : 0;
unsigned int c2 = two ? contains(two, regexp, kws, c1 + 1) : 0;
return c1 != c2;
}

Expand Down

0 comments on commit 5b0672a

Please sign in to comment.