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

Re: dumb transports not being welcomed..

From
Linus Torvalds <torvalds@osdl.org>
Date
Sep 14, 2005, 01:42 UTC
Message-ID
<Pine.LNX.4.58.0509131819310.26803@g5.osdl.org>
In-Reply-To
<Pine.LNX.4.58.0509131742240.26803@g5.osdl.org>
On Tue, 13 Sep 2005, Linus Torvalds wrote:
> 
> That said, I do think that --objects handling is _very_ CPU-hungry. The 
> offender is this old commit of mine:

No, never mind. Even without that, we end up walking a _lot_ of really uninterestng "internal" trees (ie trees where all parents were uninteresting, and they were parsed just because we had to parse a lot of commits to determine what they reached).

To explain it a bit better, let's see a common case:
HEAD:		a
	       / \
	      b   \
	     / \   \
	    c   d   \
	   /   / \   \
	  e   f   g   x
	   \ /   /   /
	    h   i   /
	     \ /   /
	      j   /
	       \ /
Old history:    k
Now, imagine that we do 
	git-rev-list b..a

which results in just two commits: 'x' and 'a' (everything else is reachable from 'b'). This is actually not that uncommon. However, in order to realize that, we had to walk through _all_ of a..k and x before we saw that 'b'..'k' were all uninteresting, and there was nothing else reachable that migt be interesting.

Now, that's pretty cheap per se. git-rev-list is optimized for this case, and hey, it's usually just a few hundred objects. Not a big deal - generating the commit list takes a small fraction of a second.

However, now the true cost of "--objects" is clear: we will walk the two "positive" trees ('a' and 'x') and look up all their objects (about 35,000 of them) interesting. So far so good. Just another fraction of a second.

HOWEVER, then we walk _every_single_uninteresting_commit_ and walk _their_ objects to say "we've got this already". And the uninteresting commits are often many more than the interesting ones - we might have had to go several weeks back to list them all. The above example is not at all extreme: we might have something like 20 interesting commits, and several hundreds of the uninteresting ones.

Now, the way to optimize things is to realize that there are two "classes" of uninteresting commits. There are the uninteresting commits that are adjacent to an interesting one (in the above example, they are "b" and "k"), and there are the uninteresting commits that are only reachable from -other- uninteresting commits ('c'..'j'). Let's call the latter class "doubly uninteresting commits", and the former class "uninteresting edge commits".

And we really don't need to walk the "doubly uninteresting" trees. But we do. Because we don't have another phase to discover the edge (we can't do that during the initial discovery phase, because we don't know if a commit is going to end up interesting in the end - we migth have another commit that we haven't seen yet that might be the parent of a commit that _looks_ interesting right now, but ends up being uninteresting because that eventually seen parent ended up being uninteresting).

In other words: I bet I could make "git-rev-list --objects" go from ten seconds to a single second if I did that edge discovery for most small incremental updates. Instead, I'm lazy, and I'm describing the problem on the list as an "educational experience", and am callously hoping that somebody will see it as an interesting challenge ;)

Btw, the above is definitely not made up. If I did my statistics right, doing "git-rev-list v2.6.14-rc1.." with the current tree results in 178 "interesting" commits, and 6251 "uninteresting" ones. And I bet 99% of those uninteresting ones are "doubly uninteresting" - and we're just wasting CPU time looking at what objects are reachable from them..

		Linus
Previous: Linus TorvaldsNext: Johannes Schindelin
Message 17 of 25 in “dumb transports not being welcomed..”
  1. Junio C HamanoSep 13, 2005
  2. Sam RavnborgSep 13, 2005
  3. Junio C HamanoSep 13, 2005
  4. Sam RavnborgSep 13, 2005
  5. Junio C HamanoSep 13, 2005
  6. Jeff GarzikSep 13, 2005
  7. Junio C HamanoSep 13, 2005
  8. Jeff GarzikSep 14, 2005
  9. Linus TorvaldsSep 13, 2005
  10. Junio C HamanoSep 13, 2005
  11. Linus TorvaldsSep 13, 2005
  12. Junio C HamanoSep 13, 2005
  13. Kay SieversSep 14, 2005
  14. Junio C HamanoSep 14, 2005
  15. Johannes SchindelinSep 14, 2005
  16. Linus TorvaldsSep 14, 2005
  17. Linus TorvaldsSep 14, 2005
  18. Johannes SchindelinSep 14, 2005
  19. Linus TorvaldsSep 14, 2005
  20. Junio C HamanoSep 15, 2005
  21. Sven VerdoolaegeSep 14, 2005
  22. Junio C HamanoSep 14, 2005
  23. Jon LoeligerSep 14, 2005
  24. Junio C HamanoSep 14, 2005
  25. Jon LoeligerSep 14, 2005

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.