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

Re: [PATCH 0/3] fast textconv

From
Michael J Gruber <git@drmicha.warpmail.net>
Date
Mar 28, 2010, 16:09 UTC
Message-ID
<4BAF7F3F.5020604@drmicha.warpmail.net>
In-Reply-To
<20100328145301.GA26213@coredump.intra.peff.net>
Jeff King venit, vidit, dixit 28.03.2010 16:53:
Show 72 quoted lines
> The normal textconv procedure is to dump the binary file to a tempfile
> (optionally using a working tree file if available), then run the
> textconv helper to produce a textual version on stdout. This is a very
> convenient interface, as helpers don't need to be aware of git at all
> and many standard commands can be used without wrappers.
> 
> Unfortunately, it can be slow for large binary files. We spool the file
> to disk before invoking the textconv helper, so the helper has no way to
> do any optimizations. For example, the helper may need only part of the
> file (e.g., when showing metadata at the beginning of a media file), or
> it may implement a caching scheme to avoid repeating expensive
> conversions.
> 
> This series introduces a "fast textconv", which does not automatically
> spool a tempfile, but instead gives the helper program the sha1 of the
> blob to be converted.
> 
> Here are some timings from my photo repository, on a commit with 37
> JPEGs and 8 AVIs. Each file had two lines added to its exif metadata.
> My textconv helper is a perl script that dumps the exif tags, and
> implements its own caching scheme.
> 
>   $ time git show >/dev/null ;# before patch
>   real    0m13.818s
>   user    0m12.137s
>   sys     0m1.552s
> 
>   $ time git show >/dev/null ;# after patch, first run
>   real    0m15.076s
>   user    0m13.321s
>   sys     0m1.772s
> 
>   $ time git show >/dev/null ;# after patch, subsequent runs
>   real    0m2.502s
>   user    0m1.820s
>   sys     0m0.592s
> 
> So you can see a 5.5x speedup. The first run is a little bit slower,
> presumably due to the extra git-cat-file calls by the helper.
> 
> The speedup is purely from caching; I am not using the "we only need to
> read the first part of the file" optimization. My files are only a few
> megabytes. Probably that would be more useful for people storing files
> in the hundreds of megabytes, where a full cat-file will cause a lot of
> unwanted I/O.
> 
> There are two things I'm still not 100% happy with:
> 
>  1. 2.5 seconds is still a little slower than I would like. The slowness
>     comes from the fact that my helper is written in perl, and therefore
>     perl gets invoked for each diff. I could try collecting all of the
>     to-be-textconv'd files at the beginning of the diff process and just
>     invoking the helper once. But that means we need to store the
>     results in core, and they could potentially be long (in my case,
>     they are only a few hundred bytes, but somebody could potentially be
>     textconv'ing a large documents).
> 
>  2. It is up to the helper to implement a caching layer. This offers a
>     lot of flexibility, but it means each helper must implement its own.
>     It also means we have to run the helper even for a cache hit, which
>     causes slowness.
> 
>     An alternative would be for git to support textconv caching
>     natively, probably by using the notes mechanism to map blob sha1's
>     to their textconv'd contents. But that opens a whole can of worms
>     with how the cache is managed. If I change my textconv helper to
>     produce different results, how do I invalidate the cache? Should it
>     happen automatically if I change the contents of
>     diff.$method.textconv? Or do I need to do it manually (you will
>     still need to do it manually if, e.g., you upgrade your textconv
>     helper. Git can't know about that). How do I evict entries if the
>     cache gets too large when notes are stored as a history?

Really, "Notes!" was my first thought even before reading 2. Happy to have found a like mind :)

This would still need a mechanism where the conv helper gets the blob's SHA1 - hey, it's there in your patch...

How about:
Set fasttextconv=notestextconv
notestextconv does the following:
- If $sha1 has a note in refs/notes/bikeshed display it.
- If not create one and then display it.
In fact, the creation could be done using the textconv setting!

Pruning the cache is done be deleting the refs/notes/bikeshed ref, truncating it by truncating it's DAG (filter-branch...).

Cheers, Michael

Previous: Jeff KingNext: Jeff King
Message 11 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.