@matheusbsbs / matheus-bagliano / commits / f13ca7cef5
Fork 0

name-rev: put struct rev_name into commit slab

The commit slab commit_rev_name contains a pointer to a struct rev_name, and the actual struct is allocated separatly. Avoid that allocation and pointer indirection by storing the full struct in the commit slab. Use the tip_name member pointer to determine if the returned struct is initialized. Performance in the Linux repository measured with hyperfine before: Benchmark #1: ./git -C ../linux/ name-rev --all Time (mean ± σ): 953.5 ms ± 6.3 ms [User: 901.2 ms, System: 52.1 ms] Range (min … max): 945.2 ms … 968.5 ms 10 runs ... and with this patch: Benchmark #1: ./git -C ../linux/ name-rev --all Time (mean ± σ): 851.0 ms ± 3.1 ms [User: 807.4 ms, System: 43.6 ms] Range (min … max): 846.7 ms … 857.0 ms 10 runs Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Feb 4, 2020 at 22:22 UTC f13ca7cef51cc709c645f9da97f09a150bdb2cac
1 file changed +11 -9
builtin/name-rev.c
+11 -9
@@ -24,7 +24,7 @@ struct rev_name {
24 int from_tag;
25 };
26
27 -define_commit_slab(commit_rev_name, struct rev_name *);
27 +define_commit_slab(commit_rev_name, struct rev_name);
28
29 static timestamp_t cutoff = TIME_MAX;
30 static struct commit_rev_name rev_names;
@@ -32,11 +32,16 @@ static struct commit_rev_name rev_names;
32 /* How many generations are maximally preferred over _one_ merge traversal? */
33 #define MERGE_TRAVERSAL_WEIGHT 65535
34
35 +static int is_valid_rev_name(const struct rev_name *name)
36 +{
37 + return name && name->tip_name;
38 +}
39 +
40 static struct rev_name *get_commit_rev_name(const struct commit *commit)
41 {
37 - struct rev_name **slot = commit_rev_name_peek(&rev_names, commit);
42 + struct rev_name *name = commit_rev_name_peek(&rev_names, commit);
43
39 - return slot ? *slot : NULL;
44 + return is_valid_rev_name(name) ? name : NULL;
45 }
46
47 static int is_better_name(struct rev_name *name,
@@ -81,15 +86,12 @@ static struct rev_name *create_or_update_name(struct commit *commit,
86 int generation, int distance,
87 int from_tag)
88 {
84 - struct rev_name **slot = commit_rev_name_at(&rev_names, commit);
85 - struct rev_name *name = *slot;
89 + struct rev_name *name = commit_rev_name_at(&rev_names, commit);
90
87 - if (name && !is_better_name(name, taggerdate, distance, from_tag))
91 + if (is_valid_rev_name(name) &&
92 + !is_better_name(name, taggerdate, distance, from_tag))
93 return NULL;
94
90 - if (!name)
91 - name = *slot = xmalloc(sizeof(*name));
92 -
95 name->tip_name = tip_name;
96 name->taggerdate = taggerdate;
97 name->generation = generation;