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

Re: [PATCH v3 8/8] pack-objects: add third name hash version

From
Taylor Blau <me@ttaylorr.com>
Date
Jan 22, 2025, 22:37 UTC
Message-ID
<Z5FzE1XpBlEyhK2T@nand.local>
In-Reply-To
<3d63954f318e5133630b1f579a399a123e434cf8.1734715194.git.gitgitgadget@gmail.com>
On Fri, Dec 20, 2024 at 05:19:54PM +0000, Derrick Stolee via GitGitGadget wrote:
Show 23 quoted lines
> Create a third name hash function and extend the '--name-hash-version'
> option in 'git pack-objects' and 'git repack' to understand it. This
> hash version abandons all efforts for locality and focuses on creating a
> somewhat uniformly-distributed hash function to minimize collisions.
>
> We can observe the effect of this collision avoidance in a large
> internal monorepo that suffered from collisions in the previous
> versions. The updates to p5314-name-hash.sh show these results:
>
> Test                               this tree
> --------------------------------------------------
> 5314.1: paths at head                       227.3K
> 5314.2: distinct hash value: v1              72.3K
> 5314.3: maximum multiplicity: v1             14.4K
> 5314.4: distinct hash value: v2             166.5K
> 5314.5: maximum multiplicity: v2               138
> 5314.6: distinct hash value: v3             227.3K
> 5314.7: maximum multiplicity: v3                 2
>
> These results demonstrate that of the 227,000+ paths, nearly all of them
> find distinct hash values. The maximum multiplicity is 2, improved from
> 138 in the v2 hash function. The v2 hash function also had only 166K
> distinct values, so it had a wide spread of collisions.

I had a little trouble reading this section of the commit message. I think the framing makes sense (v2 has collisions which can impact pack generation time and/or size), but this section explains v3 I think one level too deep.

This comparison (and the one below it for v3) shows a reduction in distinct hash values and the maximum multiplicity (I'm assuming for colliding hash values, in which case I might suggest renaming it as "maximum collisions").

But I imagine that many readers will primarily care about the effect of the new hash function on pack generation time and size. You show that below, but I think that it should potentially appear earlier in the commit message.

Alternatively, you could consider leaving the time/size table alone where it is, and devote an extra sentence or two to explaining the impact on repacking time/size that the two metrics above (distinct hash values, multiplicity/collisions) have on the repacking time/size.

Show 26 quoted lines
> A more modest improvement is available in the open source fluentui repo
> [1] with these results:
>
> Test                               this tree
> --------------------------------------------------
> 5314.1: paths at head                        19.5K
> 5314.2: distinct hash value: v1               8.2K
> 5314.3: maximum multiplicity: v1               279
> 5314.4: distinct hash value: v2              17.8K
> 5314.5: maximum multiplicity: v2                44
> 5314.6: distinct hash value: v3              19.5K
> 5314.7: maximum multiplicity: v3                 1
>
> [1] https://github.com/microsoft/fluentui
>
> However, it is important to demonstrate the effectiveness of this
> function in the context of compressing a repository. We can use
> p5313-pack-objects.sh to measure these changes. I will use a simplified
> table summarizing the output of that performance test.
>
>  | Test      | V1 Time | V2 Time | V3 Time | V1 Size | V2 Size | V3 Size |
>  |-----------|---------|---------|---------|---------|---------|---------|
>  | Thin Pack |  0.37 s |  0.12 s |  0.07 s |   1.2 M |  22.0 K |  20.4 K |
>  | Big Pack  |  2.04 s |  2.80 s |  1.40 s |  20.4 M |  25.9 M |  19.2 M |
>  | Shallow   |  1.41 s |  1.77 s |  1.27 s |  34.4 M |  33.7 M |  34.8 M |
>  | Repack    | 95.70 s | 33.68 s | 20.88 s | 439.3 M | 160.5 M | 169.1 M |

OK, now we get to the chart that I demonstrates the effects of each hash function on the most externally visible effects. Are these measurements taken from the fluentui repo, or somewhere else? In either case, it may be worth mentioning.

Show 29 quoted lines
> Here, there are some performance improvements on a time basis, and the
> thin and big packs are somewhat smaller in v3. The shallow and repacked
> packs are somewhat bigger, though, compared to v2.
>
> Two repositories that have very few collisions in the v1 name hash are
> the Git and Linux repositories. Here are their stats for p5313:
>
> Git:
>
>  | Test      | V1 Time | V2 Time | V3 Time | V1 Size | V2 Size | V3 Size |
>  |-----------|---------|---------|---------|---------|---------|---------|
>  | Thin Pack |  0.02 s |  0.02 s |  0.02 s |   1.1 K |   1.1 K |  15.3 K |
>  | Big Pack  |  1.69 s |  1.95 s |  1.67 s |  13.5 M |  14.5 M |  14.9 M |
>  | Shallow   |  1.26 s |  1.29 s |  1.16 s |  12.0 M |  12.2 M |  12.5 M |
>  | Repack    | 29.51 s | 29.01 s | 29.08 s | 237.7 M | 238.2 M | 237.7 M |
>
> Linux:
>
>  | Test      | V1 Time  | V2 Time  | V3 Time  | V1 Size | V2 Size | V3 Size |
>  |-----------|----------|----------|----------|---------|---------|---------|
>  | Thin Pack |   0.17 s |   0.07 s |   0.07 s |   4.6 K |   4.6 K |   6.8 K |
>  | Big Pack  |  17.88 s |  12.35 s |  12.14 s | 201.1 M | 149.1 M | 160.4 M |
>  | Shallow   |  11.05 s |  22.94 s |  22.16 s | 269.2 M | 273.8 M | 271.8 M |
>  | Repack    | 727.39 s | 566.95 s | 539.33 s |   2.5 G |   2.5 G |   2.6 G |
>
> These repositories make good use of the cross-path deltas that come
> about from the v1 name hash function, so they already had mixed results
> with the v2 function. The v3 function is generally worse for these
> repositories.
I appreciate you sharing some counterexamples as well.
Show 7 quoted lines
> While the fluentui repo had an increase in size using the v3 name hash,
> the others had modest improvements over the v2 name hash. But those
> modest improvements are dwarfed by the difference from v1 to v2, so it
> is unlikely that the regression seen in the other scenarios (packfiles
> that are not from full repacks) will be worth using v3 over v2. That is,
> unless there are enough collisions even with v2 that the full repack
> scenario has larger improvements than these.

This is the paragraph that I thought most about (both while reading the above sections, and then again after seeing my internal thoughts written down here).

It seems like the general conclusion is that v2 is a strict improvement on v1 in almost all cases. v3 appears to be an improvement on v2 in some cases, and a regression (as you note) in others. But I think more importantly (again as you note) is that the improvement from v1 to v2 is so pronounced that it's unlikely that the regression from v2 to v3 will matter or even be noticeable in most cases.

Are there easy ways to detect when v3 would be an improvement over v2? If so, then I think exposing those detection mechanisms to users (either as an automated tool or through documentation, perhaps in git-packing(7), which is perfect for this sort of discussion) would be worthwhile. Then users could make an informed decision about which hash function to use for their repositories.

But if there isn't such a mechanism, then I wonder what would drive a user to choose v3 over v2. I suspect the answer is that curious users would try repacking both ways, and then stick with whichever one has a bigger impact on the metric(s) they care most about.

If that's the case, I suspect that v2 will be the dominant choice, especially if we consider changing the default from 1 to 2 at some point in the future. Given all of that, I share your feeling that it may be worth dropping this patch entirely. It is true that some cases will be worse off (at least compared to v2) without this part of the series. But it gets us out of having to support v3 forever, or go through the process of deprecating it. I'd like the project to avoid both of those if possible, especially if we don't anticipate many users will select v3 over v2.

Thanks, Taylor

Previous: Derrick Stolee via GitGitGadgetNext: Derrick Stolee
Message 78 of 93 in “pack-objects: Create an alternative name hash algorithm (recreated)”
  1. 0/7 pack-objects: Create an alternative name hash algorithm (recreated)Derrick Stolee via GitGitGadget, Nov 5, 2024
  2. 1/7 pack-objects: add --full-name-hash optionDerrick Stolee via GitGitGadget, Nov 5, 2024
  3. Taylor BlauNov 21, 2024
  4. Taylor BlauNov 21, 2024
  5. Junio C HamanoNov 21, 2024
  6. Derrick StoleeNov 22, 2024
  7. Derrick StoleeNov 22, 2024
  8. Patrick SteinhardtNov 26, 2024
  9. 2/7 repack: add --full-name-hash optionDerrick Stolee via GitGitGadget, Nov 5, 2024
  10. Taylor BlauNov 21, 2024
  11. Derrick StoleeNov 22, 2024
  12. 3/7 pack-objects: add GIT_TEST_FULL_NAME_HASHDerrick Stolee via GitGitGadget, Nov 5, 2024
  13. Taylor BlauNov 21, 2024
  14. Derrick StoleeNov 22, 2024
  15. Jonathan TanNov 22, 2024
  16. Junio C HamanoNov 22, 2024
  17. Jonathan TanNov 22, 2024
  18. Junio C HamanoNov 25, 2024
  19. Jonathan TanNov 25, 2024
  20. Junio C HamanoNov 26, 2024
  21. Patrick SteinhardtNov 26, 2024
  22. 4/7 git-repack: update usage to match docsDerrick Stolee via GitGitGadget, Nov 5, 2024
  23. Taylor BlauNov 21, 2024
  24. Derrick StoleeNov 22, 2024
  25. 5/7 p5313: add size comparison testDerrick Stolee via GitGitGadget, Nov 5, 2024
  26. Taylor BlauNov 21, 2024
  27. Derrick StoleeNov 22, 2024
  28. Patrick SteinhardtNov 26, 2024
  29. 6/7 pack-objects: disable --full-name-hash when shallowDerrick Stolee via GitGitGadget, Nov 5, 2024
  30. Taylor BlauNov 21, 2024
  31. Derrick StoleeNov 22, 2024
  32. 7/7 test-tool: add helper for name-hash valuesDerrick Stolee via GitGitGadget, Nov 5, 2024
  33. Taylor BlauNov 21, 2024
  34. Jonathan TanNov 22, 2024
  35. Jonathan TanNov 21, 2024
  36. Junio C HamanoNov 22, 2024
  37. Junio C HamanoNov 22, 2024
  38. Derrick StoleeNov 22, 2024
  39. Junio C HamanoNov 24, 2024
  40. Jonathan TanNov 22, 2024
  41. 0/8 pack-objects: Create an alternative name hash algorithm (recreated)Derrick Stolee via GitGitGadget, Dec 2, 2024
  42. 1/8 pack-objects: create new name-hash function versionJonathan Tan via GitGitGadget, Dec 2, 2024
  43. karthik nayakDec 4, 2024
  44. Junio C HamanoDec 4, 2024
  45. karthik nayakDec 5, 2024
  46. Jonathan TanDec 9, 2024
  47. Junio C HamanoDec 10, 2024
  48. 2/8 pack-objects: add --name-hash-version optionDerrick Stolee via GitGitGadget, Dec 2, 2024
  49. karthik nayakDec 4, 2024
  50. 3/8 repack: add --name-hash-version optionDerrick Stolee via GitGitGadget, Dec 2, 2024
  51. karthik nayakDec 4, 2024
  52. 4/8 pack-objects: add GIT_TEST_NAME_HASH_VERSIONDerrick Stolee via GitGitGadget, Dec 2, 2024
  53. karthik nayakDec 4, 2024
  54. Jonathan TanDec 9, 2024
  55. Derrick StoleeDec 20, 2024
  56. 5/8 p5313: add size comparison testDerrick Stolee via GitGitGadget, Dec 2, 2024
  57. 6/8 test-tool: add helper for name-hash valuesDerrick Stolee via GitGitGadget, Dec 2, 2024
  58. 7/8 pack-objects: prevent name hash version changeDerrick Stolee via GitGitGadget, Dec 2, 2024
  59. 8/8 pack-objects: add third name hash versionDerrick Stolee via GitGitGadget, Dec 2, 2024
  60. Junio C HamanoDec 3, 2024
  61. Derrick StoleeDec 4, 2024
  62. Junio C HamanoDec 4, 2024
  63. 0/8 pack-objects: Create an alternative name hash algorithm (recreated)Derrick Stolee via GitGitGadget, Dec 20, 2024
  64. 1/8 pack-objects: create new name-hash function versionJonathan Tan via GitGitGadget, Dec 20, 2024
  65. Taylor BlauJan 22, 2025
  66. 2/8 pack-objects: add --name-hash-version optionDerrick Stolee via GitGitGadget, Dec 20, 2024
  67. Taylor BlauJan 22, 2025
  68. Derrick StoleeJan 24, 2025
  69. 3/8 repack: add --name-hash-version optionDerrick Stolee via GitGitGadget, Dec 20, 2024
  70. Taylor BlauJan 22, 2025
  71. 4/8 pack-objects: add GIT_TEST_NAME_HASH_VERSIONDerrick Stolee via GitGitGadget, Dec 20, 2024
  72. Taylor BlauJan 22, 2025
  73. 5/8 p5313: add size comparison testDerrick Stolee via GitGitGadget, Dec 20, 2024
  74. 6/8 test-tool: add helper for name-hash valuesDerrick Stolee via GitGitGadget, Dec 20, 2024
  75. 7/8 pack-objects: prevent name hash version changeDerrick Stolee via GitGitGadget, Dec 20, 2024
  76. Taylor BlauJan 22, 2025
  77. 8/8 pack-objects: add third name hash versionDerrick Stolee via GitGitGadget, Dec 20, 2024
  78. Taylor BlauJan 22, 2025
  79. Derrick StoleeJan 24, 2025
  80. Derrick StoleeJan 21, 2025
  81. Taylor BlauJan 22, 2025
  82. Derrick StoleeJan 24, 2025
  83. 0/7 pack-objects: Create an alternative name hash algorithm (recreated)Derrick Stolee via GitGitGadget, Jan 27, 2025
  84. 1/7 pack-objects: create new name-hash function versionJonathan Tan via GitGitGadget, Jan 27, 2025
  85. 3/7 repack: add --name-hash-version optionDerrick Stolee via GitGitGadget, Jan 27, 2025
  86. 2/7 pack-objects: add --name-hash-version optionDerrick Stolee via GitGitGadget, Jan 27, 2025
  87. Junio C HamanoJan 27, 2025
  88. Derrick StoleeJan 29, 2025
  89. 4/7 pack-objects: add GIT_TEST_NAME_HASH_VERSIONDerrick Stolee via GitGitGadget, Jan 27, 2025
  90. 5/7 p5313: add size comparison testDerrick Stolee via GitGitGadget, Jan 27, 2025
  91. 6/7 test-tool: add helper for name-hash valuesDerrick Stolee via GitGitGadget, Jan 27, 2025
  92. 7/7 pack-objects: prevent name hash version changeDerrick Stolee via GitGitGadget, Jan 27, 2025
  93. Taylor BlauJan 31, 2025

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.