Subject: [PATCH v2 0/2] [GSOC] ref-filter: reuse output buffer

From: "ZheNing Hu via GitGitGadget" <[email-masked]>
Date: Tue, 20 Apr 2021 16:52:09 +0000

* Firstly, inlining show_ref_array_item().
 * Secondly, git for-each-ref reuse final buf for all refs output, the
   performance is slightly improved, this optimization is also applied to
   git tag -l and git branch -l.

Changes made in v2: reset err buffer in loop for code cleanness.

Thanks.

ZheNing Hu (2):
  [GSOC] ref-filter: get rid of show_ref_array_item
  [GSOC] ref-filter: reuse output buffer

 builtin/branch.c       | 10 ++++++----
 builtin/for-each-ref.c | 15 +++++++++++++--
 builtin/tag.c          | 15 +++++++++++++--
 ref-filter.c           | 25 ++++++++++---------------
 ref-filter.h           |  2 --
 5 files changed, 42 insertions(+), 25 deletions(-)

base-commit: 2e36527f23b7f6ae15e6f21ac3b08bf3fed6ee48
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-935%2Fadlternative%2Fref-filter-opt-reuse-buf-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-935/adlternative/ref-filter-opt-reuse-buf-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/935

Range-diff vs v1:

 1:  ec98f2177d90 ! 1:  7e378eef4b34 [GSOC] ref-filter: get rid of show_ref_array_item
     @@ Metadata
       ## Commit message ##
          [GSOC] ref-filter: get rid of show_ref_array_item
      
     -    Inlining the exported function `show_ref_array_item()`
     +    Inlining the exported function `show_ref_array_item()`,
          which is not providing the right level of abstraction,
          simplifies the API and can unlock improvements at the
          former call sites.
 2:  1c7a69ba072a ! 2:  a17949b9f809 [GSOC] ref-filter: reuse output buffer
     @@ Commit message
          [GSOC] ref-filter: reuse output buffer
      
          When we use `git for-each-ref`, every ref will allocate
     -    its own output strbuf. But we can reuse the final strbuf
     -    for each step ref's output.
     +    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
     @@ Commit message
          (cat-file: use a single strbuf for all output, 2018-08-14)
          to speed up the cat-file builtin.
      
     +    Helped-by: Junio C Hamano <[email-masked]>
          Helped-by: Jeff King <[email-masked]>
          Helped-by: René Scharfe <[email-masked]>
          Signed-off-by: ZheNing Hu <[email-masked]>
     @@ builtin/branch.c: static void print_ref_list(struct ref_filter *filter, struct r
       	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);
     @@ builtin/for-each-ref.c: int cmd_for_each_ref(int argc, const char **argv, const
      -		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);
     @@ builtin/tag.c: static int list_tags(struct ref_filter *filter, struct ref_sortin
      -		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);

-- 
gitgitgadget