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

Re: [PATCH v2 4/4] t/perf: add fsmonitor perf test for git diff

From
Taylor Blau <me@ttaylorr.com>
Date
Oct 19, 2020, 21:54 UTC
Message-ID
<20201019215438.GA49623@nand.local>
In-Reply-To
<f572e226bb5e4b67cc57f8d9d4732086f01190a2.1603143316.git.gitgitgadget@gmail.com>
On Mon, Oct 19, 2020 at 09:35:15PM +0000, Nipunn Koorapati via GitGitGadget wrote:
Show 8 quoted lines
> From: Nipunn Koorapati <nipunn@dropbox.com>
>
> Results for the git-diff fsmonitor optimization
> in patch in the parent-rev (using a 400k file repo to test)
>
> As you can see here - git diff with fsmonitor running is
> significantly better with this patch series (80% faster on my
> workload)!
These t/perf numbers are very helpful, at least to me.
Show 7 quoted lines
> GIT_PERF_LARGE_REPO=~/src/server ./run v2.29.0-rc1 . -- p7519-fsmonitor.sh
>
> Test                                                                     v2.29.0-rc1       this tree
> -----------------------------------------------------------------------------------------------------------------
> 7519.2: status (fsmonitor=.git/hooks/fsmonitor-watchman)                 1.46(0.82+0.64)   1.47(0.83+0.62) +0.7%
> 7519.3: status -uno (fsmonitor=.git/hooks/fsmonitor-watchman)            0.16(0.12+0.04)   0.17(0.12+0.05) +6.3%
> 7519.4: status -uall (fsmonitor=.git/hooks/fsmonitor-watchman)           1.36(0.73+0.62)   1.37(0.76+0.60) +0.7%

Looks like about 0.01sec of overhead, which seems like an acceptable trade-off for when the user has at least 10,000 files.

This reminds me; did you look at the 'git add' performance change? I recall Junio mentioning that 'git add' takes the same paths in the code.

Show 6 quoted lines
> 7519.5: diff (fsmonitor=.git/hooks/fsmonitor-watchman)                   0.85(0.22+0.63)   0.14(0.10+0.05) -83.5%
> 7519.6: diff -- 0_files (fsmonitor=.git/hooks/fsmonitor-watchman)        0.12(0.08+0.05)   0.13(0.11+0.02) +8.3%
> 7519.7: diff -- 10_files (fsmonitor=.git/hooks/fsmonitor-watchman)       0.12(0.08+0.04)   0.13(0.09+0.04) +8.3%
> 7519.8: diff -- 100_files (fsmonitor=.git/hooks/fsmonitor-watchman)      0.12(0.07+0.05)   0.13(0.07+0.06) +8.3%
> 7519.9: diff -- 1000_files (fsmonitor=.git/hooks/fsmonitor-watchman)     0.12(0.09+0.04)   0.13(0.08+0.05) +8.3%
> 7519.10: diff -- 10000_files (fsmonitor=.git/hooks/fsmonitor-watchman)   0.14(0.09+0.05)   0.13(0.10+0.03) -7.1%

OK... so having fsmonitor turned on adds an imperceptible amount of slow-down to cases where there are [0, 10000) files. But, in exchange, you get much-improved whole-tree performance, as well as single-tree performance when that tree contains at least 10,000 files.

I was going to say that this has little downside, because turning on fsmonitor is probably a good indicator that you don't have any fewer than 10,000 files in your repository, but I think that's missing the point. Likely true, but that doesn't exclude the possibility of having sub-10,000 file directories, which users may very well still be diff-ing.

So, there's a slow-down, but it's hard to complain when you consider what we get in exchange.

Show 9 quoted lines
> 7519.12: status (fsmonitor=)                                             1.67(0.93+1.49)   1.67(0.99+1.42) +0.0%
> 7519.13: status -uno (fsmonitor=)                                        0.37(0.30+0.82)   0.37(0.33+0.79) +0.0%
> 7519.14: status -uall (fsmonitor=)                                       1.58(0.97+1.35)   1.57(0.86+1.45) -0.6%
> 7519.15: diff (fsmonitor=)                                               0.34(0.28+0.83)   0.34(0.27+0.83) +0.0%
> 7519.16: diff -- 0_files (fsmonitor=)                                    0.09(0.06+0.04)   0.09(0.08+0.02) +0.0%
> 7519.17: diff -- 10_files (fsmonitor=)                                   0.09(0.07+0.03)   0.09(0.06+0.05) +0.0%
> 7519.18: diff -- 100_files (fsmonitor=)                                  0.09(0.06+0.04)   0.09(0.06+0.04) +0.0%
> 7519.19: diff -- 1000_files (fsmonitor=)                                 0.09(0.06+0.04)   0.09(0.05+0.05) +0.0%
> 7519.20: diff -- 10000_files (fsmonitor=)                                0.10(0.08+0.04)   0.10(0.06+0.05) +0.0%
Great! No slow-down without fsmonitor enabled, as expected. Fantastic.
Show 7 quoted lines
> I also added a benchmark for a tiny git diff workload w/ a pathspec.
> I see an approximately .02 second overhead added w/ and w/o fsmonitor
>
> From looking at these results, I suspected that refresh_fsmonitor
> is already happening during git diff - independent of this patch
> series' optimization. Confirmed that suspicion by breaking on
> refresh_fsmonitor.

So, the overhead that we're paying is purely the pipe+fork+exec? I.e., that watchman has already computed an answer in the earlier call, and we just have to read it again (or find out that the last results were unchanged)?

Show 11 quoted lines
> (gdb) bt  [simplified]
> 0  refresh_fsmonitor  at fsmonitor.c:176
> 1  ie_match_stat  at read-cache.c:375
> 2  match_stat_with_submodule at diff-lib.c:237
> 4  builtin_diff_files  at builtin/diff.c:260
> 5  cmd_diff  at builtin/diff.c:541
> 6  run_builtin  at git.c:450
> 7  handle_builtin  at git.c:700
> 8  run_argv  at git.c:767
> 9  cmd_main  at git.c:898
> 10 main  at common-main.c:52
:-).
Show 10 quoted lines
> Signed-off-by: Nipunn Koorapati <nipunn@dropbox.com>
> ---
>  t/perf/p7519-fsmonitor.sh | 71 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 71 insertions(+)
>
> diff --git a/t/perf/p7519-fsmonitor.sh b/t/perf/p7519-fsmonitor.sh
> index 9313d4a51d..2b4803707f 100755
> --- a/t/perf/p7519-fsmonitor.sh
> +++ b/t/perf/p7519-fsmonitor.sh
> @@ -115,6 +115,13 @@ test_expect_success "setup for fsmonitor" '

Everything in here looks very reasonable to me, except for the seq vs. test_seq() issue that I pointed out in another email in this thread.

It's too bad that we have to write these twice, but that's not the fault of your patch.

Thanks, Taylor

Previous: Taylor BlauNext: Nipunn Koorapati
Message 22 of 52 in “use fsmonitor data in git diff eliminating O(num_files) calls to lstat”
  1. 0/4 use fsmonitor data in git diff eliminating O(num_files) calls to lstatNipunn Koorapati via GitGitGadget, Oct 17, 2020
  2. 1/4 fsmonitor: use fsmonitor data in `git diff`Alex Vandiver via GitGitGadget, Oct 17, 2020
  3. Junio C HamanoOct 17, 2020
  4. Nipunn KoorapatiOct 18, 2020
  5. Taylor BlauOct 18, 2020
  6. Junio C HamanoOct 18, 2020
  7. Taylor BlauOct 18, 2020
  8. Junio C HamanoOct 19, 2020
  9. Taylor BlauOct 19, 2020
  10. Nipunn KoorapatiOct 19, 2020
  11. 2/4 t/perf/README: elaborate on output formatNipunn Koorapati via GitGitGadget, Oct 17, 2020
  12. 4/4 t/perf: add fsmonitor perf test for git diffNipunn Koorapati via GitGitGadget, Oct 17, 2020
  13. Junio C HamanoOct 17, 2020
  14. 3/4 t/perf/p7519-fsmonitor.sh: warm cache on first git statusNipunn Koorapati via GitGitGadget, Oct 17, 2020
  15. Taylor BlauOct 18, 2020
  16. 0/4 use fsmonitor data in git diff eliminating O(num_files) calls to lstatNipunn Koorapati via GitGitGadget, Oct 19, 2020
  17. 1/4 fsmonitor: use fsmonitor data in `git diff`Alex Vandiver via GitGitGadget, Oct 19, 2020
  18. 2/4 t/perf/README: elaborate on output formatNipunn Koorapati via GitGitGadget, Oct 19, 2020
  19. 3/4 t/perf/p7519-fsmonitor.sh: warm cache on first git statusNipunn Koorapati via GitGitGadget, Oct 19, 2020
  20. 4/4 t/perf: add fsmonitor perf test for git diffNipunn Koorapati via GitGitGadget, Oct 19, 2020
  21. Taylor BlauOct 19, 2020
  22. Taylor BlauOct 19, 2020
  23. Nipunn KoorapatiOct 19, 2020
  24. Taylor BlauOct 19, 2020
  25. Nipunn KoorapatiOct 19, 2020
  26. 0/7 use fsmonitor data in git diff eliminating O(num_files) calls to lstatNipunn Koorapati via GitGitGadget, Oct 19, 2020
  27. 3/7 t/perf/p7519-fsmonitor.sh: warm cache on first git statusNipunn Koorapati via GitGitGadget, Oct 19, 2020
  28. 1/7 fsmonitor: use fsmonitor data in `git diff`Alex Vandiver via GitGitGadget, Oct 19, 2020
  29. 2/7 t/perf/README: elaborate on output formatNipunn Koorapati via GitGitGadget, Oct 19, 2020
  30. 5/7 perf lint: check test-lint-shell-syntax in perf testsNipunn Koorapati via GitGitGadget, Oct 19, 2020
  31. Taylor BlauOct 20, 2020
  32. Junio C HamanoOct 20, 2020
  33. Taylor BlauOct 20, 2020
  34. Nipunn KoorapatiOct 20, 2020
  35. Nipunn KoorapatiOct 20, 2020
  36. 7/7 p7519-fsmonitor: add a git add benchmarkNipunn Koorapati via GitGitGadget, Oct 19, 2020
  37. Nipunn KoorapatiOct 19, 2020
  38. Taylor BlauOct 20, 2020
  39. 4/7 t/perf: add fsmonitor perf test for git diffNipunn Koorapati via GitGitGadget, Oct 19, 2020
  40. 6/7 p7519-fsmonitor: refactor to avoid code duplicationNipunn Koorapati via GitGitGadget, Oct 19, 2020
  41. Taylor BlauOct 20, 2020
  42. 0/7 use fsmonitor data in git diff eliminating O(num_files) calls to lstatNipunn Koorapati via GitGitGadget, Oct 20, 2020
  43. 1/7 fsmonitor: use fsmonitor data in `git diff`Alex Vandiver via GitGitGadget, Oct 20, 2020
  44. 2/7 t/perf/README: elaborate on output formatNipunn Koorapati via GitGitGadget, Oct 20, 2020
  45. 6/7 p7519-fsmonitor: refactor to avoid code duplicationNipunn Koorapati via GitGitGadget, Oct 20, 2020
  46. 3/7 t/perf/p7519-fsmonitor.sh: warm cache on first git statusNipunn Koorapati via GitGitGadget, Oct 20, 2020
  47. 5/7 perf lint: add make test-lint to perf testsNipunn Koorapati via GitGitGadget, Oct 20, 2020
  48. Taylor BlauOct 20, 2020
  49. Nipunn KoorapatiOct 20, 2020
  50. Taylor BlauOct 20, 2020
  51. 4/7 t/perf: add fsmonitor perf test for git diffNipunn Koorapati via GitGitGadget, Oct 20, 2020
  52. 7/7 p7519-fsmonitor: add a git add benchmarkNipunn Koorapati via GitGitGadget, Oct 20, 2020

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.