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

Re: Git performance on OS X

From
Linus Torvalds <torvalds@linux-foundation.org>
Date
Apr 19, 2008, 22:39 UTC
Message-ID
<alpine.LFD.1.10.0804191515120.2779@woody.linux-foundation.org>
In-Reply-To
<FEFAB19F-742A-452E-87C1-CD55AD0996DB@ai.rug.nl>
On Sun, 20 Apr 2008, Pieter de Bie wrote:
>
> I just tested this. "git status ." does 428815 (400k!) lstats, almost 10x as
> many as there are files in the repository. I'd agree that this is the reason
> it's slow on OS X :).

Yeah. I didn't look any further, but we do a total of *nine* 'lstat()' calls for each file we know about that is dirty, and *seven* when they are clean. Plus maybe a few more.

I had some patches that cut that down a lot, but some of it had to be reverted because of the subtle interactions with different internal copies of the index, and I think the case with a partial commit (which is what you have when using a pathspec) was the case that got reverted.

Maybe I should revisit it, now that we have internal support for actually keeping multiple indexes in place and being able to merge them.

Appended, in case somebody is interested, are the callchains for the different lstat() callers (for the case of a single file that was clean).

(This is with a non-pristine git source-base, so the line numbers may not match 100%, but the changes are pretty small, so it should still be an interesting set of callers)

At least two of them are due to ce_smudge_racily_clean_entry(), which in turn is because we trigger the is_racy_timestamp() test. Hmm.

And four of them are because of two cases of the pattern
	if (file_exists())
		add_file_to_cache(p->path, 0);

where the "file_exists()" first does an lstat() to see if it exists, and then "add_file_to_cache()" does an lstat() to get the stat info..

			Linus
---
First:
	#1  0x0000000000481fd7 in file_exists (f=0x1ac3f10 "Makefile") at dir.c:742
	#2  0x00000000004196bd in add_remove_files (list=0x7fff87223310) at builtin-commit.c:179
	#3  0x0000000000419aa1 in prepare_index (argc=1, argv=0x7fff872235d0, prefix=0x0) at builtin-commit.c:308
	#4  0x000000000041b3b2 in cmd_status (argc=1, argv=0x7fff872235d0, prefix=0x0) at builtin-commit.c:781
	#5  0x000000000040482e in run_command (p=0x704eb8, argc=2, argv=0x7fff872235d0) at git.c:264
	#6  0x00000000004049db in handle_internal_command (argc=2, argv=0x7fff872235d0) at git.c:394
	#7  0x0000000000404b47 in main (argc=2, argv=0x7fff872235d0) at git.c:458
Second:
	#1  0x00000000004973a0 in add_file_to_index (istate=0x7494c0, path=0x1ac3f10 "Makefile", verbose=0) at read-cache.c:471
	#2  0x00000000004196d7 in add_remove_files (list=0x7fff87223310) at builtin-commit.c:180
	#3  0x0000000000419aa1 in prepare_index (argc=1, argv=0x7fff872235d0, prefix=0x0) at builtin-commit.c:308
	#4  0x000000000041b3b2 in cmd_status (argc=1, argv=0x7fff872235d0, prefix=0x0) at builtin-commit.c:781
	#5  0x000000000040482e in run_command (p=0x704eb8, argc=2, argv=0x7fff872235d0) at git.c:264
	#6  0x00000000004049db in handle_internal_command (argc=2, argv=0x7fff872235d0) at git.c:394
	#7  0x0000000000404b47 in main (argc=2, argv=0x7fff872235d0) at git.c:458
Third:
	#1  0x00000000004992a4 in ce_smudge_racily_clean_entry (ce=0x1ac4000) at read-cache.c:1267
	#2  0x000000000049956d in write_index (istate=0x7494c0, newfd=6) at read-cache.c:1348
	#3  0x0000000000419ac7 in prepare_index (argc=1, argv=0x7fff872235d0, prefix=0x0) at builtin-commit.c:310
	#4  0x000000000041b3b2 in cmd_status (argc=1, argv=0x7fff872235d0, prefix=0x0) at builtin-commit.c:781
	#5  0x000000000040482e in run_command (p=0x704eb8, argc=2, argv=0x7fff872235d0) at git.c:264
	#6  0x00000000004049db in handle_internal_command (argc=2, argv=0x7fff872235d0) at git.c:394
	#7  0x0000000000404b47 in main (argc=2, argv=0x7fff872235d0) at git.c:458
Fourth:
	#1  0x0000000000481fd7 in file_exists (f=0x1ac3f10 "Makefile") at dir.c:742
	#2  0x00000000004196bd in add_remove_files (list=0x7fff87223310) at builtin-commit.c:179
	#3  0x0000000000419b21 in prepare_index (argc=1, argv=0x7fff872235d0, prefix=0x0) at builtin-commit.c:318
	#4  0x000000000041b3b2 in cmd_status (argc=1, argv=0x7fff872235d0, prefix=0x0) at builtin-commit.c:781
	#5  0x000000000040482e in run_command (p=0x704eb8, argc=2, argv=0x7fff872235d0) at git.c:264
	#6  0x00000000004049db in handle_internal_command (argc=2, argv=0x7fff872235d0) at git.c:394
	#7  0x0000000000404b47 in main (argc=2, argv=0x7fff872235d0) at git.c:458
Fifth:
	#1  0x00000000004973a0 in add_file_to_index (istate=0x7494c0, path=0x1ac3f10 "Makefile", verbose=0) at read-cache.c:471
	#2  0x00000000004196d7 in add_remove_files (list=0x7fff87223310) at builtin-commit.c:180
	#3  0x0000000000419b21 in prepare_index (argc=1, argv=0x7fff872235d0, prefix=0x0) at builtin-commit.c:318
	#4  0x000000000041b3b2 in cmd_status (argc=1, argv=0x7fff872235d0, prefix=0x0) at builtin-commit.c:781
	#5  0x000000000040482e in run_command (p=0x704eb8, argc=2, argv=0x7fff872235d0) at git.c:264
	#6  0x00000000004049db in handle_internal_command (argc=2, argv=0x7fff872235d0) at git.c:394
	#7  0x0000000000404b47 in main (argc=2, argv=0x7fff872235d0) at git.c:458
Sixth:
	#1  0x00000000004992a4 in ce_smudge_racily_clean_entry (ce=0x1ac4740) at read-cache.c:1267
	#2  0x000000000049956d in write_index (istate=0x7494c0, newfd=6) at read-cache.c:1348
	#3  0x0000000000419b47 in prepare_index (argc=1, argv=0x7fff872235d0, prefix=0x0) at builtin-commit.c:321
	#4  0x000000000041b3b2 in cmd_status (argc=1, argv=0x7fff872235d0, prefix=0x0) at builtin-commit.c:781
	#5  0x000000000040482e in run_command (p=0x704eb8, argc=2, argv=0x7fff872235d0) at git.c:264
	#6  0x00000000004049db in handle_internal_command (argc=2, argv=0x7fff872235d0) at git.c:394
	#7  0x0000000000404b47 in main (argc=2, argv=0x7fff872235d0) at git.c:458
Seventh:
	#1  0x0000000000475a37 in check_work_tree_entity (ce=0x1ac4870, st=0x7fff87221ea0, symcache=0x7fff87221f30 "") at diff-lib.c:343
	#2  0x0000000000475eab in run_diff_files (revs=0x7fff87222fc0, option=0) at diff-lib.c:466
	#3  0x00000000004bd62e in wt_status_print_changed (s=0x7fff872232f0) at wt-status.c:220
	#4  0x00000000004bdb1d in wt_status_print (s=0x7fff872232f0) at wt-status.c:310
	#5  0x0000000000419c0b in run_status (fp=0x37d8751760, index_file=0x711ef1 "/home/torvalds/git-test/.git/next-index-14646.lock", prefix=0x0, 
	    nowarn=0) at builtin-commit.c:349
	#6  0x000000000041b3cf in cmd_status (argc=1, argv=0x7fff872235d0, prefix=0x0) at builtin-commit.c:783
	#7  0x000000000040482e in run_command (p=0x704eb8, argc=2, argv=0x7fff872235d0) at git.c:264
	#8  0x00000000004049db in handle_internal_command (argc=2, argv=0x7fff872235d0) at git.c:394
	#9  0x0000000000404b47 in main (argc=2, argv=0x7fff872235d0) at git.c:458
Previous: Pieter de BieNext: Junio C Hamano
Message 8 of 39 in “Git performance on OS X”
  1. Pieter de BieApr 19, 2008
  2. Linus TorvaldsApr 19, 2008
  3. Linus TorvaldsApr 19, 2008
  4. Pieter de BieApr 19, 2008
  5. David KastrupApr 20, 2008
  6. Linus TorvaldsApr 19, 2008
  7. Pieter de BieApr 19, 2008
  8. Linus TorvaldsApr 19, 2008
  9. Junio C HamanoApr 20, 2008
  10. 01/02 implement a stat cacheLuciano Rocha, Apr 20, 2008
  11. 02/02 make use of the stat cacheLuciano Rocha, Apr 20, 2008
  12. Luciano RochaApr 20, 2008
  13. Linus TorvaldsApr 20, 2008
  14. Luciano RochaApr 20, 2008
  15. Linus TorvaldsApr 20, 2008
  16. Linus TorvaldsApr 20, 2008
  17. Dmitry PotapovApr 21, 2008
  18. Johan HerlandApr 21, 2008
  19. Junio C HamanoApr 21, 2008
  20. Linus TorvaldsApr 21, 2008
  21. Linus TorvaldsApr 21, 2008
  22. Junio C HamanoApr 21, 2008
  23. Linus TorvaldsApr 21, 2008
  24. Junio C HamanoApr 21, 2008
  25. David KastrupApr 21, 2008
  26. Jakub NarebskiApr 19, 2008
  27. Linus TorvaldsApr 19, 2008
  28. Linus TorvaldsApr 19, 2008
  29. Pieter de BieApr 19, 2008
  30. Linus TorvaldsApr 19, 2008
  31. Roman ShaposhnikApr 19, 2008
  32. Pieter de BieApr 19, 2008
  33. Linus TorvaldsApr 20, 2008
  34. Roman ShaposhnikApr 20, 2008
  35. Pieter de BieApr 19, 2008
  36. Linus TorvaldsApr 20, 2008
  37. Dmitry PotapovApr 20, 2008
  38. David KastrupApr 20, 2008
  39. Linus TorvaldsApr 19, 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.