summaryrefslogtreecommitdiff
path: root/strbuf.h
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2015-04-16 04:53:56 -0400
committerJunio C Hamano <gitster@pobox.com>2015-04-16 08:15:05 -0700
commitfec501dae8bf6c8fdcd4124c94f37c4cbc26ba29 (patch)
treedecc7ddca9950146d203ecbd5c7cf68d66018eca /strbuf.h
parent260d408e32363a9e76d0fea3056563d4fb51f29e (diff)
downloadgit-fec501dae8bf6c8fdcd4124c94f37c4cbc26ba29.tar.gz
strbuf_addch: avoid calling strbuf_grow
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>
Diffstat (limited to 'strbuf.h')
-rw-r--r--strbuf.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/strbuf.h b/strbuf.h
index 1883494ca3..01c5c6371b 100644
--- 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';
}