diff mbox series

pack-bitmap: avoid traversal of objects referenced by uninteresting tag

Message ID e342077ed116fb47c6a0fa645abd5558310efb09.1615993858.git.ps@pks.im (mailing list archive)
State Superseded
Headers show
Series pack-bitmap: avoid traversal of objects referenced by uninteresting tag | expand

Commit Message

Patrick Steinhardt March 17, 2021, 3:11 p.m. UTC
When preparing the bitmap walk, we first establish the set of of have
and want objects by iterating over the set of pending objects: if an
object is marked as uninteresting, it's declared as an object we already
have, otherwise as an object we want. These two sets are then used to
compute which transitively referenced objects we need to obtain.

One special case here are tag objects: when a tag is requested, we
resolve it to its first not-tag object and add both resolved objects as
well as the tag itself into either the have or want set. Given that the
uninteresting-property always propagates to referenced objects, it is
clear that if the tag is uninteresting, so are its children and vice
versa. But we fail to propagate the flag, which effectively means that
referenced objects will always be interesting except for the case where
they have already been marked as uninteresting explicitly.

This mislabeling does not impact correctness: we now have it in our
"wants" set, and given that we later do an `AND NOT` of the bitmaps of
"wants" and "haves" sets it is clear that the result must be the same.
But we now start to needlessly traverse the tag's referenced objects in
case it is uninteresting, even though we know that each referenced
object will be uninteresting anyway. In the worst case, this can lead to
a complete graph walk just to establish that we do not care for any
object.

Fix the issue by propagating the `UNINTERESTING` flag to pointees of tag
objects and add a benchmark with negative revisions to p5310. This shows
some nice performance benefits, tested with linux.git:

Test                                                  HEAD                   HEAD~
--------------------------------------------------------------------------------------------------------
5310.2: repack to disk                                194.96(183.59+16.01)   195.98(184.04+16.67) +0.5%
5310.3: simulated clone                               26.09(25.04+1.05)      26.11(24.95+1.16) +0.1%
5310.4: simulated fetch                               2.64(5.25+0.72)        2.59(4.99+0.72) -1.9%
5310.5: pack to file (bitmap)                         58.70(58.19+5.66)      58.99(58.66+5.52) +0.5%
5310.6: rev-list (commits)                            1.46(1.19+0.27)        1.47(1.21+0.25) +0.7%
5310.7: rev-list (objects)                            15.54(14.48+1.06)      16.17(15.06+1.11) +4.1%
5310.8: rev-list with negation (objects)              0.09(0.07+0.02)        23.13(21.53+1.60) +25600.0%
5310.9: rev-list count with blob:none                 12.40(11.43+0.97)      12.38(11.33+1.04) -0.2%
5310.10: rev-list count with blob:limit=1k            18.14(16.09+2.05)      18.26(16.18+2.07) +0.7%
5310.11: rev-list count with tree:0                   1.71(1.32+0.39)        1.67(1.31+0.36) -2.3%
5310.12: simulated partial clone                      20.20(19.15+1.04)      20.45(19.34+1.10) +1.2%
5310.14: clone (partial bitmap)                       12.68(13.89+1.03)      12.84(13.91+1.03) +1.3%
5310.15: pack to file (partial bitmap)                42.10(45.33+2.76)      42.30(45.41+2.76) +0.5%
5310.16: rev-list with tree filter (partial bitmap)   0.47(0.30+0.16)        0.45(0.30+0.14) -4.3%

While most benchmarks are probably in the range of noise, the newly
added 5310.8 benchmark shows a performance improvement of 25600%.

Signed-off-by: Patrick Steinhardt <ps@pks.im>.
---
 pack-bitmap.c                | 1 +
 t/perf/p5310-pack-bitmaps.sh | 4 ++++
 2 files changed, 5 insertions(+)

Comments

Junio C Hamano March 19, 2021, 12:13 a.m. UTC | #1
Patrick Steinhardt <ps@pks.im> writes:

> While most benchmarks are probably in the range of noise, the newly
> added 5310.8 benchmark shows a performance improvement of 25600%.

which sounds impressive, but ...

> +test_perf 'rev-list with negation (objects)' '
> +	git rev-list --not --all --use-bitmap-index --objects >/dev/null
> +'

... is this an interesting use case to begin with, without any
positive end?

> +
>  test_perf 'rev-list count with blob:none' '
>  	git rev-list --use-bitmap-index --count --objects --all \
>  		--filter=blob:none >/dev/null
Patrick Steinhardt March 22, 2021, 12:16 p.m. UTC | #2
On Thu, Mar 18, 2021 at 05:13:58PM -0700, Junio C Hamano wrote:
> Patrick Steinhardt <ps@pks.im> writes:
> 
> > While most benchmarks are probably in the range of noise, the newly
> > added 5310.8 benchmark shows a performance improvement of 25600%.
> 
> which sounds impressive, but ...
> 
> > +test_perf 'rev-list with negation (objects)' '
> > +	git rev-list --not --all --use-bitmap-index --objects >/dev/null
> > +'
> 
> ... is this an interesting use case to begin with, without any
> positive end?

Not at all, but it's easy enough to end up with something similar. E.g.
`git rev-list $TAG --not --all` wouldn't typically show anything at all
if `$TAG` is covered by a revision either, but it shows the same
speedup.

I've changed the benchmark to be a bit more realistic here. I've also
added a second benchmark which shows a modest 16-20% speedup when using
`git rev-list HEAD --not $TAG`, where `HEAD` and `$TAG` point to the
same commit. There's probably other cases that may show speedups, but I
hope those are good enough for now.

Patrick
diff mbox series

Patch

diff --git a/pack-bitmap.c b/pack-bitmap.c
index 1f69b5fa85..11118a92e8 100644
--- a/pack-bitmap.c
+++ b/pack-bitmap.c
@@ -997,6 +997,7 @@  struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,
 				object_list_insert(object, &wants);
 
 			object = parse_object_or_die(get_tagged_oid(tag), NULL);
+			object->flags |= (tag->object.flags & UNINTERESTING);
 		}
 
 		if (object->flags & UNINTERESTING)
diff --git a/t/perf/p5310-pack-bitmaps.sh b/t/perf/p5310-pack-bitmaps.sh
index b3e725f031..2910c818ac 100755
--- a/t/perf/p5310-pack-bitmaps.sh
+++ b/t/perf/p5310-pack-bitmaps.sh
@@ -43,6 +43,10 @@  test_perf 'rev-list (objects)' '
 	git rev-list --all --use-bitmap-index --objects >/dev/null
 '
 
+test_perf 'rev-list with negation (objects)' '
+	git rev-list --not --all --use-bitmap-index --objects >/dev/null
+'
+
 test_perf 'rev-list count with blob:none' '
 	git rev-list --use-bitmap-index --count --objects --all \
 		--filter=blob:none >/dev/null