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

[PATCH 5/5] cat-file: use packed_object_info() for --batch-all-objects

From
Jeff King <peff@peff.net>
Date
Oct 5, 2021, 20:38 UTC
Message-ID
<YVy3rPuUal0+9iJs@coredump.intra.peff.net>
In-Reply-To
<YVy1sx8Xb1xMLFQT@coredump.intra.peff.net>

When "cat-file --batch-all-objects" iterates over each object, it knows where to find each one. But when we look up details of the object, we don't use that information at all.

This patch teaches it to use the pack/offset pair when we're iterating over objects in a pack. This yields a measurable speed improvement (timings on a fully packed clone of linux.git):

  Benchmark #1: ./git.old cat-file --batch-all-objects --unordered --batch-check="%(objecttype) %(objectname)"
    Time (mean ± σ):      8.128 s ±  0.118 s    [User: 7.968 s, System: 0.156 s]
    Range (min … max):    8.007 s …  8.301 s    10 runs
  Benchmark #2: ./git.new cat-file --batch-all-objects --unordered --batch-check="%(objecttype) %(objectname)"
    Time (mean ± σ):      4.294 s ±  0.064 s    [User: 4.167 s, System: 0.125 s]
    Range (min … max):    4.227 s …  4.457 s    10 runs
  Summary
    './git.new cat-file --batch-all-objects --unordered --batch-check="%(objecttype) %(objectname)"' ran
      1.89 ± 0.04 times faster than './git.old cat-file --batch-all-objects --unordered --batch-check="%(objecttype) %(objectname)"

The implementation is pretty simple: we just call packed_object_info() instead of oid_object_info_extended() when we can. Most of the changes are just plumbing the pack/offset pair through the callstack. There is one subtlety: replace lookups are not handled by packed_object_info(). But since those are disabled for --batch-all-objects, and since we'll only have pack info when that option is in effect, we don't have to worry about that.

There are a few limitations to this optimization which we could address with further work:

 - I didn't bother recording when we found an object loose. Technically
   this could save us doing a fruitless lookup in the pack index. But
   opening and mmap-ing a loose object is so expensive in the first
   place that this doesn't matter much. And if your repository is large
   enough to care about per-object performance, most objects are going
   to be packed anyway.
 - This works only in --unordered mode. For the sorted mode, we'd have
   to record the pack/offset pair as part of our oid-collection. That's
   more code, plus at least 16 extra bytes of heap per object. It would
   probably still be a net win in runtime, but we'd need to measure.
 - For --batch, this still helps us with getting the object metadata,
   but we still do a from-scratch lookup for the object contents. This
   probably doesn't matter that much, because the lookup cost will be
   much smaller relative to the cost of actually unpacking and printing
   the objects.
   For small objects, we could probably swap out read_object_file() for
   using packed_object_info() with a "object_info.contentp" to get the
   contents. But we'd still need to deal with streaming for larger
   objects. A better path forward here is to teach the initial
   oid_object_info_extended() / packed_object_info() calls to retrieve
   the contents of smaller objects while they are already being
   accessed. That would save the extra lookup entirely. But it's a
   non-trivial feature to add to the object_info code, so I left it for
   now.
Signed-off-by: Jeff King <peff@peff.net>
---
I have some patches for the "give me the content in a single call if
it's small" idea, but they need some polishing. It also doesn't produce
as spectacular a speedup as I'd hoped, which is why I threw it on the
back burner. I think it's just because actually dealing with the object
content is so much more expensive than an extra lookup.
 builtin/cat-file.c | 45 +++++++++++++++++++++++++++++++--------------
 1 file changed, 31 insertions(+), 14 deletions(-)
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index b533935d5c..219ff5628d 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -358,15 +358,26 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
 static void batch_object_write(const char *obj_name,
 			       struct strbuf *scratch,
 			       struct batch_options *opt,
-			       struct expand_data *data)
+			       struct expand_data *data,
+			       struct packed_git *pack,
+			       off_t offset)
 {
-	if (!data->skip_object_info &&
-	    oid_object_info_extended(the_repository, &data->oid, &data->info,
-				     OBJECT_INFO_LOOKUP_REPLACE) < 0) {
-		printf("%s missing\n",
-		       obj_name ? obj_name : oid_to_hex(&data->oid));
-		fflush(stdout);
-		return;
+	if (!data->skip_object_info) {
+		int ret;
+
+		if (pack)
+			ret = packed_object_info(the_repository, pack, offset,
+						 &data->info);
+		else
+			ret = oid_object_info_extended(the_repository,
+						       &data->oid, &data->info,
+						       OBJECT_INFO_LOOKUP_REPLACE);
+		if (ret < 0) {
+			printf("%s missing\n",
+			       obj_name ? obj_name : oid_to_hex(&data->oid));
+			fflush(stdout);
+			return;
+		}
 	}
 
 	strbuf_reset(scratch);
@@ -428,7 +439,7 @@ static void batch_one_object(const char *obj_name,
 		return;
 	}
 
-	batch_object_write(obj_name, scratch, opt, data);
+	batch_object_write(obj_name, scratch, opt, data, NULL, 0);
 }
 
 struct object_cb_data {
@@ -442,7 +453,8 @@ static int batch_object_cb(const struct object_id *oid, void *vdata)
 {
 	struct object_cb_data *data = vdata;
 	oidcpy(&data->expand->oid, oid);
-	batch_object_write(NULL, data->scratch, data->opt, data->expand);
+	batch_object_write(NULL, data->scratch, data->opt, data->expand,
+			   NULL, 0);
 	return 0;
 }
 
@@ -463,31 +475,36 @@ static int collect_packed_object(const struct object_id *oid,
 	return 0;
 }
 
-static int batch_unordered_object(const struct object_id *oid, void *vdata)
+static int batch_unordered_object(const struct object_id *oid,
+				  struct packed_git *pack, off_t offset,
+				  void *vdata)
 {
 	struct object_cb_data *data = vdata;
 
 	if (oidset_insert(data->seen, oid))
 		return 0;
 
 	oidcpy(&data->expand->oid, oid);
-	batch_object_write(NULL, data->scratch, data->opt, data->expand);
+	batch_object_write(NULL, data->scratch, data->opt, data->expand,
+			   pack, offset);
 	return 0;
 }
 
 static int batch_unordered_loose(const struct object_id *oid,
 				 const char *path,
 				 void *data)
 {
-	return batch_unordered_object(oid, data);
+	return batch_unordered_object(oid, NULL, 0, data);
 }
 
 static int batch_unordered_packed(const struct object_id *oid,
 				  struct packed_git *pack,
 				  uint32_t pos,
 				  void *data)
 {
-	return batch_unordered_object(oid, data);
+	return batch_unordered_object(oid, pack,
+				      nth_packed_object_offset(pack, pos),
+				      data);
 }
 
 static int batch_objects(struct batch_options *opt)
-- 
2.33.0.1231.g45ae28b974
Previous: Jeff KingNext: Junio C Hamano
Message 97 of 101 in “cat-file replace handling and optimization”
  1. 0/5 cat-file replace handling and optimizationJeff King, Oct 5, 2021
  2. 1/5 t1006: clean up broken objectsJeff King, Oct 5, 2021
  3. 2/5 cat-file: mention --unordered along with --batch-all-objectsJeff King, Oct 5, 2021
  4. Ævar Arnfjörð BjarmasonOct 5, 2021
  5. Jeff KingOct 5, 2021
  6. Ævar Arnfjörð BjarmasonOct 6, 2021
  7. Jeff KingOct 6, 2021
  8. Ævar Arnfjörð BjarmasonOct 7, 2021
  9. Jeff KingOct 8, 2021
  10. Ævar Arnfjörð BjarmasonOct 8, 2021
  11. Junio C HamanoOct 8, 2021
  12. Jeff KingOct 8, 2021
  13. Junio C HamanoOct 8, 2021
  14. 00/10 cat-file: better usage UX & error messagesÆvar Arnfjörð Bjarmason, Nov 6, 2021
  15. 01/10 cat-file tests: test bad usageÆvar Arnfjörð Bjarmason, Nov 6, 2021
  16. Eric SunshineNov 7, 2021
  17. 02/10 cat-file tests: test messaging on bad objects/pathsÆvar Arnfjörð Bjarmason, Nov 6, 2021
  18. 03/10 parse-options API: add a usage_msg_optf()Ævar Arnfjörð Bjarmason, Nov 6, 2021
  19. 04/10 cat-file docs: fix SYNOPSIS and "-h" outputÆvar Arnfjörð Bjarmason, Nov 6, 2021
  20. 05/10 cat-file: move "usage" variable to cmd_cat_file()Ævar Arnfjörð Bjarmason, Nov 6, 2021
  21. 06/10 cat-file: make --batch-all-objects a CMDMODEÆvar Arnfjörð Bjarmason, Nov 6, 2021
  22. Eric SunshineNov 7, 2021
  23. 07/10 cat-file: fix remaining usage bugsÆvar Arnfjörð Bjarmason, Nov 6, 2021
  24. 08/10 cat-file: correct and improve usage informationÆvar Arnfjörð Bjarmason, Nov 6, 2021
  25. 09/10 object-name.c: don't have GET_OID_ONLY_TO_DIE imply *_QUIETLYÆvar Arnfjörð Bjarmason, Nov 6, 2021
  26. Eric SunshineNov 7, 2021
  27. 10/10 cat-file: improve --(textconv|filters) disambiguationÆvar Arnfjörð Bjarmason, Nov 6, 2021
  28. 00/10 cat-file: better usage UX & error messagesÆvar Arnfjörð Bjarmason, Nov 12, 2021
  29. 01/10 cat-file tests: test bad usageÆvar Arnfjörð Bjarmason, Nov 12, 2021
  30. 04/10 cat-file docs: fix SYNOPSIS and "-h" outputÆvar Arnfjörð Bjarmason, Nov 12, 2021
  31. 03/10 parse-options API: add a usage_msg_optf()Ævar Arnfjörð Bjarmason, Nov 12, 2021
  32. 02/10 cat-file tests: test messaging on bad objects/pathsÆvar Arnfjörð Bjarmason, Nov 12, 2021
  33. 05/10 cat-file: move "usage" variable to cmd_cat_file()Ævar Arnfjörð Bjarmason, Nov 12, 2021
  34. 06/10 cat-file: make --batch-all-objects a CMDMODEÆvar Arnfjörð Bjarmason, Nov 12, 2021
  35. 07/10 cat-file: fix remaining usage bugsÆvar Arnfjörð Bjarmason, Nov 12, 2021
  36. 08/10 cat-file: correct and improve usage informationÆvar Arnfjörð Bjarmason, Nov 12, 2021
  37. 09/10 object-name.c: don't have GET_OID_ONLY_TO_DIE imply *_QUIETLYÆvar Arnfjörð Bjarmason, Nov 12, 2021
  38. 10/10 cat-file: improve --(textconv|filters) disambiguationÆvar Arnfjörð Bjarmason, Nov 12, 2021
  39. 00/10 cat-file: better usage UX & error messagesÆvar Arnfjörð Bjarmason, Nov 29, 2021
  40. 02/10 cat-file tests: test messaging on bad objects/pathsÆvar Arnfjörð Bjarmason, Nov 29, 2021
  41. 01/10 cat-file tests: test bad usageÆvar Arnfjörð Bjarmason, Nov 29, 2021
  42. 03/10 parse-options API: add a usage_msg_optf()Ævar Arnfjörð Bjarmason, Nov 29, 2021
  43. 04/10 cat-file docs: fix SYNOPSIS and "-h" outputÆvar Arnfjörð Bjarmason, Nov 29, 2021
  44. 05/10 cat-file: move "usage" variable to cmd_cat_file()Ævar Arnfjörð Bjarmason, Nov 29, 2021
  45. 06/10 cat-file: make --batch-all-objects a CMDMODEÆvar Arnfjörð Bjarmason, Nov 29, 2021
  46. 07/10 cat-file: fix remaining usage bugsÆvar Arnfjörð Bjarmason, Nov 29, 2021
  47. Jiang XinDec 6, 2021
  48. 10/10 cat-file: use GET_OID_ONLY_TO_DIE in --(textconv|filters)Ævar Arnfjörð Bjarmason, Nov 29, 2021
  49. 09/10 object-name.c: don't have GET_OID_ONLY_TO_DIE imply *_QUIETLYÆvar Arnfjörð Bjarmason, Nov 29, 2021
  50. 08/10 cat-file: correct and improve usage informationÆvar Arnfjörð Bjarmason, Nov 29, 2021
  51. 00/10 cat-file: better usage UX & error messagesÆvar Arnfjörð Bjarmason, Dec 8, 2021
  52. 01/10 cat-file tests: test bad usageÆvar Arnfjörð Bjarmason, Dec 8, 2021
  53. 02/10 cat-file tests: test messaging on bad objects/pathsÆvar Arnfjörð Bjarmason, Dec 8, 2021
  54. 04/10 cat-file docs: fix SYNOPSIS and "-h" outputÆvar Arnfjörð Bjarmason, Dec 8, 2021
  55. 03/10 parse-options API: add a usage_msg_optf()Ævar Arnfjörð Bjarmason, Dec 8, 2021
  56. 05/10 cat-file: move "usage" variable to cmd_cat_file()Ævar Arnfjörð Bjarmason, Dec 8, 2021
  57. 06/10 cat-file: make --batch-all-objects a CMDMODEÆvar Arnfjörð Bjarmason, Dec 8, 2021
  58. 07/10 cat-file: fix remaining usage bugsÆvar Arnfjörð Bjarmason, Dec 8, 2021
  59. John CaiDec 20, 2021
  60. 08/10 cat-file: correct and improve usage informationÆvar Arnfjörð Bjarmason, Dec 8, 2021
  61. 09/10 object-name.c: don't have GET_OID_ONLY_TO_DIE imply *_QUIETLYÆvar Arnfjörð Bjarmason, Dec 8, 2021
  62. 10/10 cat-file: use GET_OID_ONLY_TO_DIE in --(textconv|filters)Ævar Arnfjörð Bjarmason, Dec 8, 2021
  63. 00/10 cat-file: better usage UX & error messagesÆvar Arnfjörð Bjarmason, Dec 22, 2021
  64. 02/10 cat-file tests: test messaging on bad objects/pathsÆvar Arnfjörð Bjarmason, Dec 22, 2021
  65. 01/10 cat-file tests: test bad usageÆvar Arnfjörð Bjarmason, Dec 22, 2021
  66. 03/10 parse-options API: add a usage_msg_optf()Ævar Arnfjörð Bjarmason, Dec 22, 2021
  67. 04/10 cat-file docs: fix SYNOPSIS and "-h" outputÆvar Arnfjörð Bjarmason, Dec 22, 2021
  68. 05/10 cat-file: move "usage" variable to cmd_cat_file()Ævar Arnfjörð Bjarmason, Dec 22, 2021
  69. 06/10 cat-file: make --batch-all-objects a CMDMODEÆvar Arnfjörð Bjarmason, Dec 22, 2021
  70. 07/10 cat-file: fix remaining usage bugsÆvar Arnfjörð Bjarmason, Dec 22, 2021
  71. Junio C HamanoDec 26, 2021
  72. 10/10 cat-file: use GET_OID_ONLY_TO_DIE in --(textconv|filters)Ævar Arnfjörð Bjarmason, Dec 22, 2021
  73. 08/10 cat-file: correct and improve usage informationÆvar Arnfjörð Bjarmason, Dec 22, 2021
  74. 09/10 object-name.c: don't have GET_OID_ONLY_TO_DIE imply *_QUIETLYÆvar Arnfjörð Bjarmason, Dec 22, 2021
  75. 00/10 cat-file: better usage UX & error messagesÆvar Arnfjörð Bjarmason, Dec 28, 2021
  76. 01/10 cat-file tests: test bad usageÆvar Arnfjörð Bjarmason, Dec 28, 2021
  77. 02/10 cat-file tests: test messaging on bad objects/pathsÆvar Arnfjörð Bjarmason, Dec 28, 2021
  78. 03/10 parse-options API: add a usage_msg_optf()Ævar Arnfjörð Bjarmason, Dec 28, 2021
  79. 04/10 cat-file docs: fix SYNOPSIS and "-h" outputÆvar Arnfjörð Bjarmason, Dec 28, 2021
  80. 05/10 cat-file: move "usage" variable to cmd_cat_file()Ævar Arnfjörð Bjarmason, Dec 28, 2021
  81. 07/10 cat-file: fix remaining usage bugsÆvar Arnfjörð Bjarmason, Dec 28, 2021
  82. 08/10 cat-file: correct and improve usage informationÆvar Arnfjörð Bjarmason, Dec 28, 2021
  83. Jiang XinJan 8, 2022
  84. 0/2 fixups for issues in next-merged ab/cat-fileÆvar Arnfjörð Bjarmason, Jan 10, 2022
  85. 1/2 cat-file: don't whitespace-pad "(...)" in SYNOPSIS and usage outputÆvar Arnfjörð Bjarmason, Jan 10, 2022
  86. 2/2 cat-file: s/_/-/ in typo'd usage_msg_optf() messageÆvar Arnfjörð Bjarmason, Jan 10, 2022
  87. Junio C HamanoJan 10, 2022
  88. Taylor BlauJan 11, 2022
  89. Junio C HamanoJan 12, 2022
  90. 09/10 object-name.c: don't have GET_OID_ONLY_TO_DIE imply *_QUIETLYÆvar Arnfjörð Bjarmason, Dec 28, 2021
  91. 10/10 cat-file: use GET_OID_ONLY_TO_DIE in --(textconv|filters)Ævar Arnfjörð Bjarmason, Dec 28, 2021
  92. 06/10 cat-file: make --batch-all-objects a CMDMODEÆvar Arnfjörð Bjarmason, Dec 28, 2021
  93. 3/5 cat-file: disable refs/replace with --batch-all-objectsJeff King, Oct 5, 2021
  94. Derrick StoleeOct 6, 2021
  95. Junio C HamanoOct 7, 2021
  96. 4/5 cat-file: split ordered/unordered batch-all-objects callbacksJeff King, Oct 5, 2021
  97. 5/5 cat-file: use packed_object_info() for --batch-all-objectsJeff King, Oct 5, 2021
  98. Junio C HamanoOct 7, 2021
  99. Jeff KingOct 8, 2021
  100. Derrick StoleeOct 6, 2021
  101. Jeff KingOct 7, 2021

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.