Skip to content

Commit 844c3f0

Browse files
adlternativegitster
authored andcommitted
ref-filter: reuse output buffer
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>
1 parent 22f69a8 commit 844c3f0

File tree

3 files changed

+20
-16
lines changed

3 files changed

+20
-16
lines changed

builtin/branch.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,8 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
411411
{
412412
int i;
413413
struct ref_array array;
414+
struct strbuf out = STRBUF_INIT;
415+
struct strbuf err = STRBUF_INIT;
414416
int maxwidth = 0;
415417
const char *remote_prefix = "";
416418
char *to_free = NULL;
@@ -440,8 +442,8 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
440442
ref_array_sort(sorting, &array);
441443

442444
for (i = 0; i < array.nr; i++) {
443-
struct strbuf out = STRBUF_INIT;
444-
struct strbuf err = STRBUF_INIT;
445+
strbuf_reset(&err);
446+
strbuf_reset(&out);
445447
if (format_ref_array_item(array.items[i], format, &out, &err))
446448
die("%s", err.buf);
447449
if (column_active(colopts)) {
@@ -452,10 +454,10 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
452454
fwrite(out.buf, 1, out.len, stdout);
453455
putchar('\n');
454456
}
455-
strbuf_release(&err);
456-
strbuf_release(&out);
457457
}
458458

459+
strbuf_release(&err);
460+
strbuf_release(&out);
459461
ref_array_clear(&array);
460462
free(to_free);
461463
}

builtin/for-each-ref.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
2222
struct ref_array array;
2323
struct ref_filter filter;
2424
struct ref_format format = REF_FORMAT_INIT;
25+
struct strbuf output = STRBUF_INIT;
26+
struct strbuf err = STRBUF_INIT;
2527

2628
struct option opts[] = {
2729
OPT_BIT('s', "shell", &format.quote_style,
@@ -81,17 +83,16 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
8183
if (!maxcount || array.nr < maxcount)
8284
maxcount = array.nr;
8385
for (i = 0; i < maxcount; i++) {
84-
struct strbuf output = STRBUF_INIT;
85-
struct strbuf err = STRBUF_INIT;
86-
86+
strbuf_reset(&err);
87+
strbuf_reset(&output);
8788
if (format_ref_array_item(array.items[i], &format, &output, &err))
8889
die("%s", err.buf);
8990
fwrite(output.buf, 1, output.len, stdout);
9091
putchar('\n');
91-
92-
strbuf_release(&err);
93-
strbuf_release(&output);
9492
}
93+
94+
strbuf_release(&err);
95+
strbuf_release(&output);
9596
ref_array_clear(&array);
9697
return 0;
9798
}

builtin/tag.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
3939
struct ref_format *format)
4040
{
4141
struct ref_array array;
42+
struct strbuf output = STRBUF_INIT;
43+
struct strbuf err = STRBUF_INIT;
4244
char *to_free = NULL;
4345
int i;
4446

@@ -64,17 +66,16 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
6466
ref_array_sort(sorting, &array);
6567

6668
for (i = 0; i < array.nr; i++) {
67-
struct strbuf output = STRBUF_INIT;
68-
struct strbuf err = STRBUF_INIT;
69-
69+
strbuf_reset(&output);
70+
strbuf_reset(&err);
7071
if (format_ref_array_item(array.items[i], format, &output, &err))
7172
die("%s", err.buf);
7273
fwrite(output.buf, 1, output.len, stdout);
7374
putchar('\n');
74-
75-
strbuf_release(&err);
76-
strbuf_release(&output);
7775
}
76+
77+
strbuf_release(&err);
78+
strbuf_release(&output);
7879
ref_array_clear(&array);
7980
free(to_free);
8081

0 commit comments

Comments
 (0)