Skip to content

Commit b9584c5

Browse files
peffgitster
authored andcommitted
ref-filter: avoid parsing tagged objects in match_points_at()
When we peel tags to check if they match a --points-at oid, we recursively parse the tagged object to see if it is also a tag. But since the tag itself tells us the type of the object it points to (and even gives us the appropriate object struct via its "tagged" member), we can use that directly. We do still have to make sure to call parse_tag() before looking at each tag. This is redundant for the outermost tag (since we did call parse_object() to find its type), but that's OK; parse_tag() is smart enough to make this a noop when the tag has already been parsed. In my clone of linux.git, with 782 tags (and only 3 non-tags), this yields a significant speedup (bringing us back where we were before the commit before this one started recursively dereferencing tags): Benchmark 1: ./git.old for-each-ref --points-at=HEAD --format="%(refname)" Time (mean ± σ): 20.3 ms ± 0.5 ms [User: 11.1 ms, System: 9.1 ms] Range (min … max): 19.6 ms … 21.5 ms 141 runs Benchmark 2: ./git.new for-each-ref --points-at=HEAD --format="%(refname)" Time (mean ± σ): 11.4 ms ± 0.2 ms [User: 6.3 ms, System: 5.0 ms] Range (min … max): 11.0 ms … 12.2 ms 250 runs Summary './git.new for-each-ref --points-at=HEAD --format="%(refname)"' ran 1.79 ± 0.05 times faster than './git.old for-each-ref --points-at=HEAD --format="%(refname)"' Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 468887f commit b9584c5

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

ref-filter.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2346,10 +2346,18 @@ static const struct object_id *match_points_at(struct oid_array *points_at,
23462346
return oid;
23472347
obj = parse_object(the_repository, oid);
23482348
while (obj && obj->type == OBJ_TAG) {
2349-
oid = get_tagged_oid((struct tag *)obj);
2349+
struct tag *tag = (struct tag *)obj;
2350+
2351+
if (parse_tag(tag) < 0) {
2352+
obj = NULL;
2353+
break;
2354+
}
2355+
2356+
oid = get_tagged_oid(tag);
23502357
if (oid_array_lookup(points_at, oid) >= 0)
23512358
return oid;
2352-
obj = parse_object(the_repository, oid);
2359+
2360+
obj = tag->tagged;
23532361
}
23542362
if (!obj)
23552363
die(_("malformed object at '%s'"), refname);

0 commit comments

Comments
 (0)