strbuf_addch: avoid calling strbuf_grow
authorJeff King <peff@peff.net>
Thu, 16 Apr 2015 08:53:56 +0000 (04:53 -0400)
committerJunio C Hamano <gitster@pobox.com>
Thu, 16 Apr 2015 15:15:05 +0000 (08:15 -0700)
We mark strbuf_addch as inline, because we expect it may be
called from a tight loop. However, the first thing it does
is call the non-inline strbuf_grow(), which can handle
arbitrary-sized growth. Since we know that we only need a
single character, we can use the inline strbuf_avail() to
quickly check whether we need to grow at all.

Our check is redundant when we do call strbuf_grow(), but
that's OK. The common case is that we avoid calling it at
all, and we have made that case faster.

On a silly pathological case:

perl -le '
print "[core]";
print "key$_ = value$_" for (1..1000000)
' >input
git config -f input core.key1

this dropped the time to run git-config from:

real 0m0.159s
user 0m0.152s
sys 0m0.004s

to:

real 0m0.140s
user 0m0.136s
sys 0m0.004s

for a savings of 12%.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
strbuf.h
index 1883494ca3ad4931640c2a295c94800e287c1664..01c5c6371b8e43686f335704a67a59a1d82dbe3b 100644 (file)
--- a/strbuf.h
+++ b/strbuf.h
@@ -205,7 +205,8 @@ extern int strbuf_cmp(const struct strbuf *, const struct strbuf *);
  */
 static inline void strbuf_addch(struct strbuf *sb, int c)
 {
-       strbuf_grow(sb, 1);
+       if (!strbuf_avail(sb))
+               strbuf_grow(sb, 1);
        sb->buf[sb->len++] = c;
        sb->buf[sb->len] = '\0';
 }