[PATCH 2/2] Use strbuf for struct xdiff_emit_state's remainder

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH 2/2] Use strbuf for struct xdiff_emit_state's remainder

brian downing-4
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 <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html