[PATCH 2/2] Use strbuf for struct xdiff_emit_state's remainder
From: Brian Downing <hidden>
Date: 2016-06-15 22:45:09
Subsystem:
the rest · Maintainer:
Linus Torvalds
Continually xreallocing and freeing the remainder member of struct xdiff_emit_state was a noticeable performance hit. Use a strbuf instead. This yields a decent performance improvement on "git blame" on certain repositories. For example, before this commit: $ time git blame -M -C -C -p --incremental server.c >/dev/null 101.52user 0.17system 1:41.73elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+39561minor)pagefaults 0swaps With this commit: $ time git blame -M -C -C -p --incremental server.c >/dev/null 80.38user 0.30system 1:20.81elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+50979minor)pagefaults 0swaps Signed-off-by: Brian Downing <redacted> --- xdiff-interface.c | 33 +++++++++++---------------------- xdiff-interface.h | 4 ++-- 2 files changed, 13 insertions(+), 24 deletions(-)
diff --git a/xdiff-interface.c b/xdiff-interface.c
index 9c5e277..4462177 100644
--- a/xdiff-interface.c
+++ b/xdiff-interface.c@@ -66,6 +66,7 @@ void xdiff_outf_init(xdemitcb_t *ecb, void *priv_) struct xdiff_emit_state *priv = priv_; ecb->outf = xdiff_outf; ecb->priv = priv; + strbuf_init(&priv->remainder, 0); } int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf)
@@ -76,42 +77,30 @@ int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf) for (i = 0; i < nbuf; i++) { if (mb[i].ptr[mb[i].size-1] != '\n') { /* Incomplete line */ - priv->remainder = xrealloc(priv->remainder, - priv->remainder_size + - mb[i].size); - memcpy(priv->remainder + priv->remainder_size, - mb[i].ptr, mb[i].size); - priv->remainder_size += mb[i].size; + strbuf_add(&priv->remainder, mb[i].ptr, mb[i].size); continue; } /* we have a complete line */ - if (!priv->remainder) { + if (!priv->remainder.len) { consume_one(priv, mb[i].ptr, mb[i].size); continue; } - priv->remainder = xrealloc(priv->remainder, - priv->remainder_size + - mb[i].size); - memcpy(priv->remainder + priv->remainder_size, - mb[i].ptr, mb[i].size); - consume_one(priv, priv->remainder, - priv->remainder_size + mb[i].size); - free(priv->remainder); - priv->remainder = NULL; - priv->remainder_size = 0; + strbuf_add(&priv->remainder, mb[i].ptr, mb[i].size); + consume_one(priv, priv->remainder.buf, priv->remainder.len); + strbuf_reset(&priv->remainder); } - if (priv->remainder) { - consume_one(priv, priv->remainder, priv->remainder_size); - free(priv->remainder); - priv->remainder = NULL; - priv->remainder_size = 0; + if (priv->remainder.len) { + consume_one(priv, priv->remainder.buf, priv->remainder.len); + strbuf_reset(&priv->remainder); } return 0; } void xdiff_outf_release(void *priv_) { + struct xdiff_emit_state *priv = priv_; + strbuf_release(&priv->remainder); } /*
diff --git a/xdiff-interface.h b/xdiff-interface.h
index fca6200..9b7e4a8 100644
--- a/xdiff-interface.h
+++ b/xdiff-interface.h@@ -2,6 +2,7 @@ #define XDIFF_INTERFACE_H #include "xdiff/xdiff.h" +#include "strbuf.h" struct xdiff_emit_state;
@@ -9,8 +10,7 @@ typedef void (*xdiff_emit_consume_fn)(void *, char *, unsigned long); struct xdiff_emit_state { xdiff_emit_consume_fn consume; - char *remainder; - unsigned long remainder_size; + struct strbuf remainder; }; int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *ecb);
--
1.5.6.1