diff options
author | Jeff King <peff@peff.net> | 2015-04-16 04:53:56 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2015-04-16 08:15:05 -0700 |
commit | fec501dae8bf6c8fdcd4124c94f37c4cbc26ba29 (patch) | |
tree | decc7ddca9950146d203ecbd5c7cf68d66018eca /strbuf.h | |
parent | config: use getc_unlocked when reading from file (diff) | |
download | tgif-fec501dae8bf6c8fdcd4124c94f37c4cbc26ba29.tar.xz |
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.h | 3 |
1 files changed, 2 insertions, 1 deletions
@@ -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'; } |