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>
This commit is contained in:
Jeff King 2015-04-16 04:53:56 -04:00 коммит произвёл Junio C Hamano
Родитель 260d408e32
Коммит fec501dae8
1 изменённых файлов: 2 добавлений и 1 удалений

Просмотреть файл

@ -205,6 +205,7 @@ extern int strbuf_cmp(const struct strbuf *, const struct strbuf *);
*/ */
static inline void strbuf_addch(struct strbuf *sb, int c) static inline void strbuf_addch(struct strbuf *sb, int c)
{ {
if (!strbuf_avail(sb))
strbuf_grow(sb, 1); strbuf_grow(sb, 1);
sb->buf[sb->len++] = c; sb->buf[sb->len++] = c;
sb->buf[sb->len] = '\0'; sb->buf[sb->len] = '\0';