[PATCH 5/9] strbuf_addch: avoid calling strbuf_grow
- From
Jeff King <peff@peff.net>
- Date
- Apr 16, 2015, 08:53 UTC
- Message-ID
- <20150416085356.GE17938@peff.net>
- In-Reply-To
- <20150416084733.GA17811@peff.net>
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.key1this 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> --- I doubt anybody will really notice this in practice with config files, and for the most part we do not have tight loops of strbuf_addch elsewhere. But it is such an easy optimization, I'd rather do it now while we're thinking about it.
strbuf.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/strbuf.h b/strbuf.h index 1883494..01c5c63 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'; }
-- 2.4.0.rc2.384.g7297a4a