strbuf_getwholeline: avoid calling strbuf_grow
authorJeff King <peff@peff.net>
Thu, 16 Apr 2015 08:58:54 +0000 (04:58 -0400)
committerJunio C Hamano <gitster@pobox.com>
Thu, 16 Apr 2015 15:15:05 +0000 (08:15 -0700)
As with the recent speedup to strbuf_addch, we can avoid
calling strbuf_grow() in a tight loop of single-character
adds by instead checking strbuf_avail.

Note that we would instead call strbuf_addch directly here,
but it does more work than necessary: it will NUL-terminate
the result for each character read. Instead, in this loop we
read the characters one by one and then add the terminator
manually at the end.

Running "git rev-parse refs/heads/does-not-exist" on a repo
with an extremely large (1.6GB) packed-refs file went from
(best-of-5):

real 0m10.948s
user 0m10.548s
sys 0m0.412s

to:

real 0m8.601s
user 0m8.084s
sys 0m0.524s

for a wall-clock speedup of 21%.

Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
strbuf.c
index af2bad4b561a0972e50b8dd9e04121ed09151896..921619ea681392fd6fc1e4c30556ca6596bc0b42 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -445,7 +445,8 @@ int strbuf_getwholeline(struct strbuf *sb, FILE *fp, int term)
        strbuf_reset(sb);
        flockfile(fp);
        while ((ch = getc_unlocked(fp)) != EOF) {
-               strbuf_grow(sb, 1);
+               if (!strbuf_avail(sb))
+                       strbuf_grow(sb, 1);
                sb->buf[sb->len++] = ch;
                if (ch == term)
                        break;