]> git.ipfire.org Git - thirdparty/git.git/commitdiff
name-rev: put struct rev_name into commit slab
authorRené Scharfe <l.s.r@web.de>
Tue, 4 Feb 2020 21:22:36 +0000 (22:22 +0100)
committerJunio C Hamano <gitster@pobox.com>
Wed, 5 Feb 2020 18:24:15 +0000 (10:24 -0800)
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>
builtin/name-rev.c

index 41aed436ca36219d5ee8a921dda13f09856a19bc..14381a3c646e0ce00a9117ed178374f1b030521d 100644 (file)
@@ -24,7 +24,7 @@ struct rev_name {
        int from_tag;
 };
 
-define_commit_slab(commit_rev_name, struct rev_name *);
+define_commit_slab(commit_rev_name, struct rev_name);
 
 static timestamp_t cutoff = TIME_MAX;
 static struct commit_rev_name rev_names;
@@ -32,11 +32,16 @@ static struct commit_rev_name rev_names;
 /* How many generations are maximally preferred over _one_ merge traversal? */
 #define MERGE_TRAVERSAL_WEIGHT 65535
 
+static int is_valid_rev_name(const struct rev_name *name)
+{
+       return name && name->tip_name;
+}
+
 static struct rev_name *get_commit_rev_name(const struct commit *commit)
 {
-       struct rev_name **slot = commit_rev_name_peek(&rev_names, commit);
+       struct rev_name *name = commit_rev_name_peek(&rev_names, commit);
 
-       return slot ? *slot : NULL;
+       return is_valid_rev_name(name) ? name : NULL;
 }
 
 static int is_better_name(struct rev_name *name,
@@ -81,15 +86,12 @@ static struct rev_name *create_or_update_name(struct commit *commit,
                                              int generation, int distance,
                                              int from_tag)
 {
-       struct rev_name **slot = commit_rev_name_at(&rev_names, commit);
-       struct rev_name *name = *slot;
+       struct rev_name *name = commit_rev_name_at(&rev_names, commit);
 
-       if (name && !is_better_name(name, taggerdate, distance, from_tag))
+       if (is_valid_rev_name(name) &&
+           !is_better_name(name, taggerdate, distance, from_tag))
                return NULL;
 
-       if (!name)
-               name = *slot = xmalloc(sizeof(*name));
-
        name->tip_name = tip_name;
        name->taggerdate = taggerdate;
        name->generation = generation;