From: "René Scharfe" <l.s.r@web.de>
To: Jeff King <peff@peff.net>
Cc: git@vger.kernel.org
Subject: Re: [PATCH 1/4] strbuf: add strbuf_add_uint()
Date: Wed, 13 May 2026 19:46:11 +0200 [thread overview]
Message-ID: <9e0b4f9f-ffcb-4dad-bd4f-295bbc011a1e@web.de> (raw)
In-Reply-To: <20260513162232.GB103037@coredump.intra.peff.net>
On 5/13/26 6:22 PM, Jeff King wrote:
> On Tue, May 12, 2026 at 09:32:09PM +0200, René Scharfe wrote:
>
>> The three variants were close in my tests, the no-copy variant slightly
>> winning on Apple silicon, but losing slightly more on an AMD Ryzen
>> laptop CPU. So I went with the solid choice of using an on-stack
>> buffer, same as in printf(3) (at least on BSD). Buffering at the end of
>> the strbuf was not really faster; perhaps memmove(3) is just that much
>> slower than memcpy(3).
>
> I'm not sure if you did these tests initially, or if I nerd-sniped you
> into it. Either way, I am happy to be able to hear the results. ;)
Did them before I sent the series.
>> Perhaps an optimized decimal_width() could change the picture somewhat,
>> but I don't expect a big win. On the other hand I just told you how
>> unreliable my expectations are, so there might be treasure after all. :)
>
> I got identical times for cat-file's %(objectsize:disk) running your
> version against the one below.
Similar here (git_stack is this series, git_clz is your patch on top,
git_dec uses pager.c::decimal_width()):
Benchmark 1: ./git_stack cat-file --batch-all-objects --batch-check='%(objectsize:disk)'
Time (mean ± σ): 383.5 ms ± 0.8 ms [User: 374.7 ms, System: 7.6 ms]
Range (min … max): 382.2 ms … 384.7 ms 10 runs
Benchmark 2: ./git_dec cat-file --batch-all-objects --batch-check='%(objectsize:disk)'
Time (mean ± σ): 382.5 ms ± 1.0 ms [User: 373.9 ms, System: 7.5 ms]
Range (min … max): 381.2 ms … 384.7 ms 10 runs
Benchmark 3: ./git_clz cat-file --batch-all-objects --batch-check='%(objectsize:disk)'
Time (mean ± σ): 382.5 ms ± 0.5 ms [User: 373.7 ms, System: 7.7 ms]
Range (min … max): 381.9 ms … 383.6 ms 10 runs
> Not wanting to figure out all of the
> off-by-one corner cases myself, I checked stack overflow for an easy
> recipe but couldn't find one. The version below was generated by
> chatgpt, which looks plausibly correct to me.
>
> -Peff
>
> diff --git a/strbuf.c b/strbuf.c
> index 9731ecdc1f..c26614a698 100644
> --- a/strbuf.c
> +++ b/strbuf.c
> @@ -361,16 +361,52 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
> va_end(ap);
> }
>
> +static const uint64_t powers_of_10[] = {
> + 1ULL,
> + 10ULL,
> + 100ULL,
> + 1000ULL,
> + 10000ULL,
> + 100000ULL,
> + 1000000ULL,
> + 10000000ULL,
> + 100000000ULL,
> + 1000000000ULL,
> + 10000000000ULL,
> + 100000000000ULL,
> + 1000000000000ULL,
> + 10000000000000ULL,
> + 100000000000000ULL,
> + 1000000000000000ULL,
> + 10000000000000000ULL,
> + 100000000000000000ULL,
> + 1000000000000000000ULL,
> + 10000000000000000000ULL,
> +};
> +
> +unsigned decimal_length_u64(uint64_t n)
> +{
> + if (n == 0)
> + return 1;
> +
> + unsigned b = 63 - __builtin_clzll(n);
> + /* approximate floor(log10(n)) */
> + unsigned t = (b * 1233) >> 12;
> + /* correct if estimate was low */
> + return t + 1 + (n >= powers_of_10[t + 1]);
> +}
Clever. But it seems for smallish object size numbers at least dividing
by ten repeatedly is not causing a bottleneck.
René
next prev parent reply other threads:[~2026-05-13 17:46 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-12 11:55 [PATCH 0/4] strbuf: add and use strbuf_add_uint() René Scharfe
2026-05-12 11:56 ` [PATCH 1/4] strbuf: add strbuf_add_uint() René Scharfe
2026-05-12 18:42 ` Jeff King
2026-05-12 19:32 ` René Scharfe
2026-05-13 16:22 ` Jeff King
2026-05-13 16:47 ` Jeff King
2026-05-13 16:49 ` Jeff King
2026-05-14 11:09 ` René Scharfe
2026-05-14 11:53 ` Junio C Hamano
2026-05-15 3:53 ` Jeff King
2026-05-13 17:46 ` René Scharfe [this message]
2026-05-12 11:56 ` [PATCH 2/4] cat-file: use strbuf_add_uint() René Scharfe
2026-05-12 18:46 ` Jeff King
2026-05-12 11:56 ` [PATCH 3/4] ls-files: " René Scharfe
2026-05-12 19:01 ` Jeff King
2026-05-12 20:44 ` René Scharfe
2026-05-13 16:46 ` Jeff King
2026-05-12 11:56 ` [PATCH 4/4] ls-tree: " René Scharfe
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=9e0b4f9f-ffcb-4dad-bd4f-295bbc011a1e@web.de \
--to=l.s.r@web.de \
--cc=git@vger.kernel.org \
--cc=peff@peff.net \
/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