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

Re: [PATCH 0/3] fast textconv

From
Jeff King <peff@peff.net>
Date
Mar 28, 2010, 17:34 UTC
Message-ID
<20100328173420.GA18047@coredump.intra.peff.net>
In-Reply-To
<20100328165646.GA10293@coredump.intra.peff.net>
On Sun, Mar 28, 2010 at 12:56:46PM -0400, Jeff King wrote:
Show 12 quoted lines
> Better, but not perfect. My script is below. I get:
> 
>   $ time git show >/dev/null
>   real    0m1.036s
>   user    0m0.412s
>   sys     0m0.672s
> 
> which is still a 2.5x speedup (versus my other fast-textconv solution
> earlier in the thread), but I suspect we can do better. The notes
> mechanism does some up-front work to get very fast lookups, but because
> we invoke git-notes repeatedly, we never get the amortized benefit of
> that up-front work.  Doing it in-core would fix that.

Here is a quick and dirty in-core implementation. The most notable defect is that all textconvs store under refs/notes/textconv, which is obviously bogus if you might textconv the same blob in two different ways.

It was relatively easy to code thanks to a very nice notes interface from Johan Herland. That same commit is now:

  $ time git show >/dev/null
  real    0m0.350s
  user    0m0.172s
  sys     0m0.176s
which is starting to feel sufficiently snappy.

Patch is on top of 1/3 from my earlier series (it uses some of the centralizing cleanup).

diff --git a/diff.c b/diff.c
index 3ddc05e..e1ef25e 100644
--- a/diff.c
+++ b/diff.c
@@ -14,6 +14,8 @@
 #include "userdiff.h"
 #include "sigchain.h"
 #include "submodule.h"
+#include "notes.h"
+#include "refs.h"
 
 #ifdef NO_FAST_WORKING_DIRECTORY
 #define FAST_WORKING_DIRECTORY 0
@@ -3881,19 +3883,57 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,
 	return strbuf_detach(&buf, outsize);
 }
 
+static struct notes_tree textconv_notes;
+static int textconv_notes_initialized;
+
+static const unsigned char *run_and_cache_textconv(const char *cmd,
+		struct diff_filespec *df)
+{
+	char *data;
+	size_t size;
+	unsigned char blob_sha1[20];
+	unsigned char tree_sha1[20];
+
+	data = run_textconv(cmd, df, &size);
+	if (!data)
+		die("unable to read files to diff");
+	if (write_sha1_file(data, size, "blob", blob_sha1) < 0)
+		die("unable to write textconv cache blob");
+	free(data);
+
+	add_note(&textconv_notes, df->sha1, blob_sha1, combine_notes_overwrite);
+	if (write_notes_tree(&textconv_notes, tree_sha1) < 0)
+		die("unable to write textconv cache notes tree");
+	update_ref("textconv cache update", "refs/notes/textconv",
+			tree_sha1, NULL, 0, DIE_ON_ERR);
+
+	return get_note(&textconv_notes, df->sha1);
+}
+
 static size_t fill_textconv(const char *cmd,
 			    struct diff_filespec *df,
 			    char **outbuf)
 {
-	size_t size;
+	const unsigned char *sha1;
+	unsigned long size;
+	enum object_type type;
 
 	if (!cmd) {
 		*outbuf = df->data;
 		return df->size;
 	}
 
-	*outbuf = run_textconv(cmd, df, &size);
+	if (!textconv_notes_initialized) {
+		init_notes(&textconv_notes, "refs/notes/textconv", 0, 0);
+		textconv_notes_initialized = 1;
+	}
+
+	sha1 = get_note(&textconv_notes, df->sha1);
+	if (!sha1)
+		sha1 = run_and_cache_textconv(cmd, df);
+
+	*outbuf = read_sha1_file(sha1, &type, &size);
 	if (!*outbuf)
-		die("unable to read files to diff");
+		die("unable to read textconv cache object");
 	return size;
 }
Previous: Jeff KingNext: Sverre Rabbelier
Message 15 of 19 in “fast textconv”
  1. 0/3 fast textconvJeff King, Mar 28, 2010
  2. 1/3 textconv: refactor calls to run_textconvJeff King, Mar 28, 2010
  3. 2/3 textconv: refactor to handle multiple textconv typesJeff King, Mar 28, 2010
  4. 3/3 diff: add "fasttextconv" config optionJeff King, Mar 28, 2010
  5. Johannes SixtMar 28, 2010
  6. Jeff KingMar 30, 2010
  7. diff: fix textconv error zombiesJohannes Sixt, Mar 30, 2010
  8. Junio C HamanoMar 30, 2010
  9. Johannes SixtMar 30, 2010
  10. Jeff KingMar 30, 2010
  11. Michael J GruberMar 28, 2010
  12. Jeff KingMar 28, 2010
  13. Jeff KingMar 28, 2010
  14. Jeff KingMar 28, 2010
  15. Jeff KingMar 28, 2010
  16. Sverre RabbelierMar 28, 2010
  17. Jeff KingMar 30, 2010
  18. Junio C HamanoMar 30, 2010
  19. Jeff KingMar 30, 2010

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.