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

[PATCH v2 4/5] read-tree: use 'skip_cache_tree_update' option

From
Victoria Dye via GitGitGadget <gitgitgadget@gmail.com>
Date
Nov 10, 2022, 01:57 UTC
Message-ID
<5a646bc47c911bb6b58e00574ac30afab1eec00b.1668045438.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.1411.v2.git.1668045438.gitgitgadget@gmail.com>
From: Victoria Dye <vdye@github.com>

When running 'read-tree' with a single tree and no prefix, 'prime_cache_tree()' is called after the tree is unpacked. In that situation, skip a redundant call to 'cache_tree_update()' in 'unpack_trees()' by enabling the 'skip_cache_tree_update' unpack option.

Removing the redundant cache tree update provides a substantial performance improvement to 'git read-tree <tree-ish>', as shown by a test added to 'p0006-read-tree-checkout.sh':

Test before after ---------------------------------------------------------------------- read-tree br_ballast_plus_1 3.94(1.80+1.57) 3.00(1.14+1.28) -23.9%

Note that the 'read-tree' in 't1022-read-tree-partial-clone.sh' is updated to read two trees, rather than one. The test was first introduced in d3da223f221 (cache-tree: prefetch in partial clone read-tree, 2021-07-23) to exercise the 'cache_tree_update()' code path, as used in 'git merge'. Since this patch drops the call to 'cache_tree_update()' in single-tree 'git read-tree', change the test to use the two-tree variant so that 'cache_tree_update()' is called as intended.

Signed-off-by: Victoria Dye <vdye@github.com>
---
 builtin/read-tree.c                | 4 ++++
 t/perf/p0006-read-tree-checkout.sh | 8 ++++++++
 t/t1022-read-tree-partial-clone.sh | 2 +-
 3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index f4cbe460b97..45c6652444b 100644
--- a/builtin/read-tree.c
+++ b/builtin/read-tree.c
@@ -249,6 +249,10 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix)
 	if (opts.debug_unpack)
 		opts.fn = debug_merge;
 
+	/* If we're going to prime_cache_tree later, skip cache tree update */
+	if (nr_trees == 1 && !opts.prefix)
+		opts.skip_cache_tree_update = 1;
+
 	cache_tree_free(&active_cache_tree);
 	for (i = 0; i < nr_trees; i++) {
 		struct tree *tree = trees[i];
diff --git a/t/perf/p0006-read-tree-checkout.sh b/t/perf/p0006-read-tree-checkout.sh
index c481c012d2f..325566e18eb 100755
--- a/t/perf/p0006-read-tree-checkout.sh
+++ b/t/perf/p0006-read-tree-checkout.sh
@@ -49,6 +49,14 @@ test_perf "read-tree br_base br_ballast ($nr_files)" '
 	git read-tree -n -m br_base br_ballast
 '
 
+test_perf "read-tree br_ballast_plus_1 ($nr_files)" '
+	# Run read-tree 100 times for clearer performance results & comparisons
+	for i in  $(test_seq 100)
+	do
+		git read-tree -n -m br_ballast_plus_1 || return 1
+	done
+'
+
 test_perf "switch between br_base br_ballast ($nr_files)" '
 	git checkout -q br_base &&
 	git checkout -q br_ballast
diff --git a/t/t1022-read-tree-partial-clone.sh b/t/t1022-read-tree-partial-clone.sh
index a9953b6a71c..da539716359 100755
--- a/t/t1022-read-tree-partial-clone.sh
+++ b/t/t1022-read-tree-partial-clone.sh
@@ -19,7 +19,7 @@ test_expect_success 'read-tree in partial clone prefetches in one batch' '
 	git -C server config uploadpack.allowfilter 1 &&
 	git -C server config uploadpack.allowanysha1inwant 1 &&
 	git clone --bare --filter=blob:none "file://$(pwd)/server" client &&
-	GIT_TRACE_PACKET="$(pwd)/trace" git -C client read-tree $TREE &&
+	GIT_TRACE_PACKET="$(pwd)/trace" git -C client read-tree $TREE $TREE &&
 
 	# "done" marks the end of negotiation (once per fetch). Expect that
 	# only one fetch occurs.
-- 
gitgitgadget
Previous: Victoria DyeNext: Taylor Blau
Message 19 of 31 in “Skip 'cache_tree_update()' when 'prime_cache_tree()' is called immediate after”
  1. 0/5 Skip 'cache_tree_update()' when 'prime_cache_tree()' is called immediate afterVictoria Dye via GitGitGadget, Nov 8, 2022
  2. 1/5 cache-tree: add perf test comparing update and primeVictoria Dye via GitGitGadget, Nov 8, 2022
  3. SZEDER GáborNov 10, 2022
  4. 3/5 reset: use 'skip_cache_tree_update' optionVictoria Dye via GitGitGadget, Nov 8, 2022
  5. 2/5 unpack-trees: add 'skip_cache_tree_update' optionVictoria Dye via GitGitGadget, Nov 8, 2022
  6. 5/5 rebase: use 'skip_cache_tree_update' optionVictoria Dye via GitGitGadget, Nov 8, 2022
  7. 4/5 read-tree: use 'skip_cache_tree_update' optionVictoria Dye via GitGitGadget, Nov 8, 2022
  8. Derrick StoleeNov 9, 2022
  9. Victoria DyeNov 9, 2022
  10. Derrick StoleeNov 10, 2022
  11. Taylor BlauNov 9, 2022
  12. 0/5 Skip 'cache_tree_update()' when 'prime_cache_tree()' is called immediate afterVictoria Dye via GitGitGadget, Nov 10, 2022
  13. 3/5 reset: use 'skip_cache_tree_update' optionVictoria Dye via GitGitGadget, Nov 10, 2022
  14. 2/5 unpack-trees: add 'skip_cache_tree_update' optionVictoria Dye via GitGitGadget, Nov 10, 2022
  15. 1/5 cache-tree: add perf test comparing update and primeVictoria Dye via GitGitGadget, Nov 10, 2022
  16. 5/5 rebase: use 'skip_cache_tree_update' optionVictoria Dye via GitGitGadget, Nov 10, 2022
  17. Phillip WoodNov 10, 2022
  18. Victoria DyeNov 10, 2022
  19. 4/5 read-tree: use 'skip_cache_tree_update' optionVictoria Dye via GitGitGadget, Nov 10, 2022
  20. Taylor BlauNov 10, 2022
  21. Derrick StoleeNov 10, 2022
  22. 0/5 Skip 'cache_tree_update()' when 'prime_cache_tree()' is called immediate afterVictoria Dye via GitGitGadget, Nov 10, 2022
  23. 1/5 cache-tree: add perf test comparing update and primeVictoria Dye via GitGitGadget, Nov 10, 2022
  24. 2/5 unpack-trees: add 'skip_cache_tree_update' optionVictoria Dye via GitGitGadget, Nov 10, 2022
  25. 3/5 reset: use 'skip_cache_tree_update' optionVictoria Dye via GitGitGadget, Nov 10, 2022
  26. 5/5 rebase: use 'skip_cache_tree_update' optionVictoria Dye via GitGitGadget, Nov 10, 2022
  27. 4/5 read-tree: use 'skip_cache_tree_update' optionVictoria Dye via GitGitGadget, Nov 10, 2022
  28. SZEDER GáborNov 10, 2022
  29. Victoria DyeNov 10, 2022
  30. Taylor BlauNov 11, 2022
  31. Derrick StoleeNov 14, 2022

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.