git status 的性能应该会随着 Git 2.13(2017 年第二季度)的改进而提高。
请参阅Jeff Hostetler ( )的提交 950a234(2017 年 4 月 14 日) 。(由Junio C Hamano 合并 -- --在8b6bba6 提交中,2017 年 4 月 24 日)jeffhostetler
gitster
> :重新分配时string-list
使用ALLOC_GROW
宏string_list
重新分配数组时使用ALLOC_GROW()
宏,string_list
而不是简单地将其增加 32。
这是一种性能优化。
在非常大的 repo 上的状态期间并且有许多更改,总运行时间的很大一部分用于重新分配wt_status.changes
array。
在我非常大的存储库上,此更改将时间wt_status_collect_changes_worktree()
从 125 秒减少到 45 秒。
此外,Git 2.17(2018 年第二季度)将引入一个新的跟踪,用于测量在索引繁重的操作中花费的时间。
请参阅Nguyễn Thái Ngọc Duy ( ) 的提交 ca54d9b(2018 年 1 月 27 日)。(由Junio C Hamano 合并 -- --在090dbea 提交中,2018 年 2 月 15 日)pclouds
gitster
trace
: 衡量在索引繁重的操作中花费的时间
测量所有已知的繁重代码块(对象数据库访问除外)。这应该有助于确定优化是否有效。
未优化的 git-status 会给出如下内容:
0.001791141 s: read cache ...
0.004011363 s: preload index
0.000516161 s: refresh index
0.003139257 s: git command: ... 'status' '--porcelain=2'
0.006788129 s: diff-files
0.002090267 s: diff-index
0.001885735 s: initialize name hash
0.032013138 s: read directory
0.051781209 s: git command: './git' 'status'
相同的 Git 2.17(2018 年第二季度)改进git status
了:
revision.c
: 减少对象数据库查询
在mark_parents_uninteresting()
中,我们检查是否存在目标文件以查看是否应将提交视为已解析。结果是在提交上设置“已解析”位。
修改条件以仅检查has_object_file()
结果是否会更改解析的位。
当本地分支与其上游引用不同时,“ git status
”将计算提前/落后计数。
这使用paint_down_to_common()
和命中mark_parents_uninteresting()
。
在远程分支 " " 后面的本地实例 "master" 的 Linux repo 副本上,origin/master
大约 60,000 次提交,我们发现 " git status
" 的性能从 1.42 秒变为 1.32 秒,相对差异为 -7.0%。
Git 2.24(2019 年第三季度)提出了另一种提高git status
性能的设置:
请参阅Derrick Stolee ( ) 的提交 aaf633c、提交 c6cc4c5、提交 ad0fb65、提交 31b1de6、提交 b068d9a、提交 7211b9e(2019 年 8 月 13 日)。(由Junio C Hamano 合并 -- --在提交 f4f8dfe中,2019 年 9 月 9 日)derrickstolee
gitster
repo-settings:创建 feature.manyFiles 设置
该feature.manyFiles
设置适用于工作目录中有许多文件的存储库。
通过设置index.version=4
and core.untrackedCache=true
,诸如 ' git status
' 之类的命令应该会得到改进。
但:
在 Git 2.24(2019 年第四季度)中,读取index.version
配置的代码路径因最近的更新而被破坏,该更新已得到纠正。
请参阅Derrick Stolee ( ) 的提交 c11e996(2019 年 10 月 23 日)。(由Junio C Hamano 合并 -- --在4d6fb2b 提交中,2019 年 10 月 24 日)derrickstolee
gitster
签字人:Derrick Stolee
repo_settings
在 ds/feature-macros 中将几个配置选项组合成一个结构,包括移动 7211b9e 中的“ index.version ”配置设置(“ repo-settings
:整合一些配置设置”,2019-08-13,Git v2.24.0-rc1 --合并在批次 #0中列出)。
不幸的是,该文件看起来像很多样板文件,并且显然是复制粘贴过载的一个因素,配置设置被解析为repo_config_ge_bool()
而不是repo_config_get_int()
. 这意味着设置“index.version=4”将无法正确注册,并将恢复为默认版本 3。
我在将 v2.24.0-rc0 合并到 Git 代码库的 VFS 时发现了这一点,我们真的很关心索引是在版本 4 中。
这没有被代码库捕获,因为放置的版本检查t1600-index.sh
没有足够测试“基本”场景。在这里,我们修改测试以包含这些正常设置,以防止被features.manyFiles
or覆盖GIT_INDEX_VERSION
。
虽然“默认”版本是 3,但在do_write_index()
不需要时会降级为版本 2。
由于 Git 2.33(2021 年第三季度),git status 还将更快地比较 SHA1,在写入索引文件的代码路径中使用优化的哈希文件 API。
请参阅Derrick Stolee ( ) 的提交 f6e2cd0、提交 410334e、提交 2ca245f(2021 年 5 月 18 日)和提交 68142e1(2021 年 5 月 17 日)。(由Junio C Hamano 合并 -- --在0dd2fd1 提交中,2021 年 6 月 14 日)derrickstolee
gitster
签字人:Derrick Stolee
hashfile API 使用 8KB 的硬编码缓冲区大小,并且自从它在c38138c中引入以来就一直存在(“ git-pack-objects
:使用 SHA1 csum 编写包文件”,2005-06-26,Git v0.99 --合并)。
它执行与 中的哈希缓冲区类似的功能read-cache.c
,但该代码在f279894中从 8KB 更新为 128KB (“ read-cache
:使索引写入缓冲区大小为 128K”,2021-02-18,Git v2.31.0-rc1 --合并) .
理由是do_write_index()
从 1.02 秒提高到 0.72 秒。
由于我们的最终目标是让索引编写代码使用 hashfile API,我们需要统一这个缓冲区大小以避免性能回归。
由于这些缓冲区现在在堆上,我们可以根据消费者的需要调整它们的大小。
特别是,调用者hashfd_throughput()
期望在缓冲区刷新时报告进度指示器。
这些调用者更喜欢较小的 8k 缓冲区以避免更新之间的大延迟,尤其是对于网络较慢的用户。
当不使用进度指示器时,最好使用较大的缓冲区。
通过在块格式 API 中添加一个新trace2
区域,我们可以看到 ' git multi-pack-index write
' ( man )的写入部分在 Linux 机器上从 ~1.49s 降低到 ~1.47s。
这些影响在其他文件系统上可能更加明显或减弱。