]> git.ipfire.org Git - thirdparty/git.git/commitdiff
ref-filter: reuse output buffer
authorZheNing Hu <adlternative@gmail.com>
Tue, 20 Apr 2021 16:52:11 +0000 (16:52 +0000)
committerJunio C Hamano <gitster@pobox.com>
Tue, 20 Apr 2021 18:09:50 +0000 (11:09 -0700)
When we use `git for-each-ref`, every ref will allocate
its own output strbuf and error strbuf. But we can reuse
the final strbuf for each step ref's output. The error
buffer will also be reused, despite the fact that the git
will exit when `format_ref_array_item()` return a non-zero
value and output the contents of the error buffer.

The performance for `git for-each-ref` on the Git repository
itself with performance testing tool `hyperfine` changes from
23.7 ms ± 0.9 ms to 22.2 ms ± 1.0 ms. Optimization is relatively
minor.

At the same time, we apply this optimization to `git tag -l`
and `git branch -l`.

This approach is similar to the one used by 79ed0a5
(cat-file: use a single strbuf for all output, 2018-08-14)
to speed up the cat-file builtin.

Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Jeff King <peff@peff.net>
Helped-by: René Scharfe <l.s.r@web.de>
Signed-off-by: ZheNing Hu <adlternative@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/branch.c
builtin/for-each-ref.c
builtin/tag.c

index bcc00bcf182ddf53ec4215e8362edf1c391d72e8..b23b1d1752afd724d76b263ef8253036d331a078 100644 (file)
@@ -411,6 +411,8 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
 {
        int i;
        struct ref_array array;
+       struct strbuf out = STRBUF_INIT;
+       struct strbuf err = STRBUF_INIT;
        int maxwidth = 0;
        const char *remote_prefix = "";
        char *to_free = NULL;
@@ -440,8 +442,8 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
        ref_array_sort(sorting, &array);
 
        for (i = 0; i < array.nr; i++) {
-               struct strbuf out = STRBUF_INIT;
-               struct strbuf err = STRBUF_INIT;
+               strbuf_reset(&err);
+               strbuf_reset(&out);
                if (format_ref_array_item(array.items[i], format, &out, &err))
                        die("%s", err.buf);
                if (column_active(colopts)) {
@@ -452,10 +454,10 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
                        fwrite(out.buf, 1, out.len, stdout);
                        putchar('\n');
                }
-               strbuf_release(&err);
-               strbuf_release(&out);
        }
 
+       strbuf_release(&err);
+       strbuf_release(&out);
        ref_array_clear(&array);
        free(to_free);
 }
index 8520008604e377494532afe758518ecab8c7c062..b529228c62397739d3a514df3910c12fe6668d52 100644 (file)
@@ -22,6 +22,8 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
        struct ref_array array;
        struct ref_filter filter;
        struct ref_format format = REF_FORMAT_INIT;
+       struct strbuf output = STRBUF_INIT;
+       struct strbuf err = STRBUF_INIT;
 
        struct option opts[] = {
                OPT_BIT('s', "shell", &format.quote_style,
@@ -81,17 +83,16 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
        if (!maxcount || array.nr < maxcount)
                maxcount = array.nr;
        for (i = 0; i < maxcount; i++) {
-               struct strbuf output = STRBUF_INIT;
-               struct strbuf err = STRBUF_INIT;
-
+               strbuf_reset(&err);
+               strbuf_reset(&output);
                if (format_ref_array_item(array.items[i], &format, &output, &err))
                        die("%s", err.buf);
                fwrite(output.buf, 1, output.len, stdout);
                putchar('\n');
-
-               strbuf_release(&err);
-               strbuf_release(&output);
        }
+
+       strbuf_release(&err);
+       strbuf_release(&output);
        ref_array_clear(&array);
        return 0;
 }
index d92d8e110b4d62c262b56fecf77c6b7cfe2691ec..82fcfc0982423f3c7ee90fe43d30295023cc7873 100644 (file)
@@ -39,6 +39,8 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
                     struct ref_format *format)
 {
        struct ref_array array;
+       struct strbuf output = STRBUF_INIT;
+       struct strbuf err = STRBUF_INIT;
        char *to_free = NULL;
        int i;
 
@@ -64,17 +66,16 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
        ref_array_sort(sorting, &array);
 
        for (i = 0; i < array.nr; i++) {
-               struct strbuf output = STRBUF_INIT;
-               struct strbuf err = STRBUF_INIT;
-
+               strbuf_reset(&output);
+               strbuf_reset(&err);
                if (format_ref_array_item(array.items[i], format, &output, &err))
                        die("%s", err.buf);
                fwrite(output.buf, 1, output.len, stdout);
                putchar('\n');
-
-               strbuf_release(&err);
-               strbuf_release(&output);
        }
+
+       strbuf_release(&err);
+       strbuf_release(&output);
        ref_array_clear(&array);
        free(to_free);