From: Junio C Hamano <gitster@pobox.com>
To: Siddharth Shrimali <r.siddharth.shrimali@gmail.com>
Cc: git@vger.kernel.org, ps@pks.im, jonatan@jontes.page
Subject: Re: [PATCH v2] builtin/help.c: move strbuf out of help loops
Date: Tue, 10 Mar 2026 13:33:52 -0700 [thread overview]
Message-ID: <xmqq1phrtoen.fsf@gitster.g> (raw)
In-Reply-To: <20260310160029.44605-1-r.siddharth.shrimali@gmail.com> (Siddharth Shrimali's message of "Tue, 10 Mar 2026 21:30:29 +0530")
Siddharth Shrimali <r.siddharth.shrimali@gmail.com> writes:
> In list_config_help(), a strbuf was being initialized and released
> inside two separate loops. This caused unnecessary memory allocation
> and deallocation on every iteration.
OK. strbuf_init() followed by a loop that does strbuf_reset()
followed by use of strbuf, concluded with strbuf_release() after
leaving the loop, is a fairly common pattern to optimize such a use
pattern.
> This also fixes a minor memory leak when the SHOW_CONFIG_HUMAN case
> triggers a continue.
Does it? You are essentially saying that
for (int i = 0; i < 10; i++) {
struct strbuf sb = STRBUF_INIT;
switch (SHOW_CONFIG_HUMAN) {
case SHOW_CONFIG_HUMAN:
continue;
}
}
leaks, but a strbuf merely initialized can safely be discarded
without leaking any resources, can't it?
> diff --git a/builtin/help.c b/builtin/help.c
> index 86a3d03a9b..467a0763a6 100644
> --- a/builtin/help.c
> +++ b/builtin/help.c
> @@ -134,13 +134,11 @@ static void list_config_help(enum show_config_type type)
> struct string_list keys = STRING_LIST_INIT_DUP;
> struct string_list keys_uniq = STRING_LIST_INIT_DUP;
> struct string_list_item *item;
> + struct strbuf sb = STRBUF_INIT;
>
> for (p = config_name_list; *p; p++) {
> const char *var = *p;
> - struct strbuf sb = STRBUF_INIT;
> -
A blank between the variable declaration block and the first
statement makes the code easier to follow. Loss of a blank line
here is of dubious value.
> for (e = slot_expansions; e->prefix; e++) {
> -
This removal is good.
> strbuf_reset(&sb);
So we first reset, and then start building things in sb.
> strbuf_addf(&sb, "%s.%s", e->prefix, e->placeholder);
> if (!strcasecmp(var, sb.buf)) {
> @@ -149,7 +147,6 @@ static void list_config_help(enum show_config_type type)
> break;
> }
> }
> - strbuf_release(&sb);
> if (!e->prefix)
> string_list_append(&keys, var);
We no longer have to release it inside the loop, as we will reset at
the beginning of the next iteration.
> }
> @@ -164,7 +161,7 @@ static void list_config_help(enum show_config_type type)
> const char *var = keys.items[i].string;
> const char *wildcard, *tag, *cut;
> const char *dot = NULL;
> - struct strbuf sb = STRBUF_INIT;
> + strbuf_reset(&sb);
>
The arrangement of the blank line is wrong here. The original was
the last line of a declaration block which should come before the
blank. Now you are removing it, and then adding a strbuf_reset() as
the first statement, which should come after the blank that delimits
the declarations and statements.
In any case, here we have a second loop that wants to use a scratch
strbuf, so again we reset it at the beginning of the loop before we
use it.
> switch (type) {
> case SHOW_CONFIG_HUMAN:
> @@ -195,13 +192,13 @@ static void list_config_help(enum show_config_type type)
>
> strbuf_add(&sb, var, cut - var);
> string_list_append(&keys_uniq, sb.buf);
> - strbuf_release(&sb);
>
And we no longer release it during iteration. Instead ...
> }
> string_list_clear(&keys, 0);
> string_list_remove_duplicates(&keys_uniq, 0);
> for_each_string_list_item(item, &keys_uniq)
> puts(item->string);
> + strbuf_release(&sb);
... we release after we leave the loop.
> string_list_clear(&keys_uniq, 0);
> }
Having looked at this patch, I recall somebody else is revamping
this function already, so this patch would step on their toes.
Please pay attention to what is going on in the project around the
code you are touching, and coordinate with others who are working on
the same code if necessary.
https://lore.kernel.org/git/20260228104654.80831-2-amishhhaaaa@gmail.com/
Thanks.
next prev parent reply other threads:[~2026-03-10 20:33 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-10 7:03 [PATCH] builtin/help.c: move strbuf out of help loops Siddharth Shrimali
2026-03-10 12:41 ` Patrick Steinhardt
2026-03-10 16:00 ` [PATCH v2] " Siddharth Shrimali
2026-03-10 20:33 ` Junio C Hamano [this message]
2026-03-11 18:13 ` Siddharth Shrimali
2026-03-11 19:30 ` Amisha Chhajed
2026-03-11 19:48 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqq1phrtoen.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=jonatan@jontes.page \
--cc=ps@pks.im \
--cc=r.siddharth.shrimali@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox