git/list[1] front-page[2] threads[3] people[4] search[5] about
 

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

From
Brian Downing <bdowning@lavos.net>
Date
Aug 14, 2008, 05:36 UTC
Message-ID
<1218692211-26045-2-git-send-email-bdowning@lavos.net>
In-Reply-To
<1218692211-26045-1-git-send-email-bdowning@lavos.net>

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 <bdowning@lavos.net>
---
 xdiff-interface.c |   32 ++++++++++----------------------
 xdiff-interface.h |    4 ++--
 2 files changed, 12 insertions(+), 24 deletions(-)
diff --git a/xdiff-interface.c b/xdiff-interface.c
index 828b496..bf98866 100644
--- a/xdiff-interface.c
+++ b/xdiff-interface.c
@@ -69,36 +69,22 @@ static 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;
 }
@@ -148,7 +134,9 @@ int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2,
 	int ret;
 	xecb->outf = xdiff_outf;
 	xecb->priv = state;
+	strbuf_init(&state->remainder, 0);
 	ret = xdi_diff(mf1, mf2, xpp, xecfg, xecb);
+	strbuf_release(&state->remainder);
 	return ret;
 }
 
diff --git a/xdiff-interface.h b/xdiff-interface.h
index 6f3b361..f6a1ec2 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
Previous: Brian DowningNext: Junio C Hamano
Message 9 of 14 in “Make xdiff_outf_{init,release} interface”
  1. 1/2 Make xdiff_outf_{init,release} interfaceBrian Downing, Aug 13, 2008
  2. Junio C HamanoAug 14, 2008
  3. Brian DowningAug 14, 2008
  4. Junio C HamanoAug 14, 2008
  5. 1/2 Make xdi_diff_outf interface for running xdiff_outf diffsBrian Downing, Aug 14, 2008
  6. 2/2 Use strbuf for struct xdiff_emit_state's remainderBrian Downing, Aug 14, 2008
  7. Brian DowningAug 14, 2008
  8. 1/2 Make xdi_diff_outf interface for running xdiff_outf diffsBrian Downing, Aug 14, 2008
  9. 2/2 Use strbuf for struct xdiff_emit_state's remainderBrian Downing, Aug 14, 2008
  10. Junio C HamanoAug 14, 2008
  11. Brian DowningAug 14, 2008
  12. Brian DowningAug 21, 2008
  13. Junio C HamanoAug 21, 2008
  14. Brian DowningAug 21, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.