everything_local: use "quick" object existence check
authorJeff King <peff@peff.net>
Mon, 20 Nov 2017 20:29:21 +0000 (15:29 -0500)
committerJunio C Hamano <gitster@pobox.com>
Tue, 21 Nov 2017 02:30:41 +0000 (11:30 +0900)
In b495697b82 (fetch-pack: avoid repeatedly re-scanning pack
directory, 2013-01-26), we noticed that everything_local()
could waste time trying to find and parse objects which we
_expect_ to be missing. The solution was to put
has_sha1_file() in front of parse_object() to skip the
more-expensive parse attempt.

That optimization was negated later when has_sha1_file()
learned to do the same re-scan in 45e8a74873 (has_sha1_file:
re-check pack directory before giving up, 2013-08-30).

We can restore it by using the "quick" flag to tell
has_sha1_file (actually has_object_file these days) that we
prefer speed to thoroughness for this call. See also the
fixes in 5827a0354 and 0eeb077be7 for prior art and
discussion on using the "quick" flag for these cases.

The recently-added performance regression test in p5551
demonstrates the problem. You can see the original fix:

Test b495697b82^ b495697b82
--------------------------------------------------------
5551.4: fetch 1.68(1.33+0.35) 0.87(0.69+0.18) -48.2%

and then the regression:

Test 45e8a74873^ 45e8a74873
---------------------------------------------------------
5551.4: fetch 0.96(0.77+0.19) 2.55(2.04+0.50) +165.6%

and now our fix:

Test HEAD^ HEAD
--------------------------------------------------------
5551.4: fetch 7.21(6.58+0.63) 5.47(5.04+0.43) -24.1%

You can also see that other things have gotten a lot slower
since 2013. We'll deal with those in separate patches.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
fetch-pack.c
index fbbc99c88856a773326e4bb310d30fe3021e2333..eb553cb631f9924859ec36523bc128b8c7c44250 100644 (file)
@@ -715,7 +715,8 @@ static int everything_local(struct fetch_pack_args *args,
        for (ref = *refs; ref; ref = ref->next) {
                struct object *o;
 
-               if (!has_object_file(&ref->old_oid))
+               if (!has_object_file_with_flags(&ref->old_oid,
+                                               OBJECT_INFO_QUICK))
                        continue;
 
                o = parse_object(&ref->old_oid);