Git 2.13(2017年第二季度Q2)将改进git status的性能。
请参阅提交950a234(由Jeff Hostetler(jeffhostetler
)于2017年4月14日提交)。
(由Junio C Hamano -- gitster
--合并于提交8b6bba6,于2017年4月24日)
> string-list
: 在重新分配string_list
时使用ALLOC_GROW
宏
请使用
ALLOC_GROW()
宏来重新分配
string_list
数组,而不是简单地增加32。
这是一种性能优化。
在对非常大的存储库进行状态检查时,如果有许多更改,则总运行时间的相当大比例将花费在重新分配wt_status.changes
数组上。
此更改将我的非常大的存储库中wt_status_collect_changes_worktree()
的时间从125秒减少到45秒。
此外,Git 2.17(2018年第二季度)将引入一种新的跟踪方式,用于测量索引密集操作中时间的消耗。
请参见
提交 ca54d9b(2018年1月27日),由
Nguyễn Thái Ngọc Duy(pclouds
)撰写。
(由Junio C Hamano -- gitster
--合并到提交 090dbea,2018年2月15日)
trace
:测量索引密集操作中时间的消耗
All the known heavy code blocks are measured (except object database
access). This should help identify if an optimization is effective or
not.
An unoptimized git-status would give something like below:
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()
中,我们检查对象文件的存在以确定是否应将提交视为已分析。结果是设置提交的“parsed”位。
修改条件,只有当结果更改已解析位时,才检查has_object_file()
。
当本地分支与上游引用不同时,“git status
”将计算ahead/behind数量。
这使用paint_down_to_common()
并命中mark_parents_uninteresting()
。
对于Linux存储库的副本,其本地“master”实例比远程分支“origin/master
”落后约60,000次提交,“git status
”的性能从1.42秒降至1.32秒,相对差异为-7.0%。
Git 2.24 (Q3 2019) 提供了另一个设置来提高 git status
的性能:
请看 提交 aaf633c, 提交 c6cc4c5, 提交 ad0fb65, 提交 31b1de6, 提交 b068d9a, 提交 7211b9e (2019年8月13日) 作者为 Derrick Stolee (derrickstolee
)。
(由Junio C Hamano -- gitster
--于提交 f4f8dfe合并,2019年9月9日)
repo-settings: 创建 feature.manyFiles 设置
feature.manyFiles
设置适用于工作目录中有许多文件的仓库。
通过设置 index.version=4
和 core.untrackedCache=true
,例如 'git status
' 命令应该会得到改善。
但是:
从 Git 2.24(2019年第四季度)开始,读取 index.version
配置的代码路径在最近的更新中被破坏了,这已经得到了修正。
请看提交 c11e996 (2019年10月23日),由Derrick Stolee (derrickstolee
)提交。
(在提交 4d6fb2b中由Junio C Hamano -- gitster
--合并,于2019年10月24日)
由Derrick Stolee签署
多个配置选项被合并到ds/feature-macros中的
repo_settings
结构中,包括“index.version”配置设置的移动
7211b9e(“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合并到VFS for Git代码库中时发现了这个问题,我们非常关心索引是否在版本4中。由于在
t1600-index.sh
中放置的版本检查没有足够测试“基本”场景,所以代码库没有发现这个问题。在这里,我们修改测试以包括这些普通设置,以免被
features.manyFiles
或
GIT_INDEX_VERSION
覆盖。虽然“默认”版本是3,但当不必要时,它在
do_write_index()
中降级为版本2。
git status
命令也会比以前更快地比较 SHA1,这得益于 Git 2.33(2021 年第三季度)中使用了一个优化的哈希文件 API,用于编写索引文件的代码路径。
请查看提交 f6e2cd0, 提交 410334e, 提交 2ca245f (2021年5月18日),以及提交 68142e1 (2021年5月17日) 的内容,作者为Derrick Stolee (derrickstolee
)。
(由Junio C Hamano -- gitster
--于提交 0dd2fd1合并,日期为2021年6月14日)
Signed-off-by: Derrick Stolee
hashfile API使用8KB的硬编码缓冲区,自
c38138c(“
git-pack-objects
: write the pack files with a SHA1 csum”,2005-06-26,Git v0.99 --
merge)引入以来一直如此。它执行类似于
read-cache.c
中的哈希缓冲区的功能,但该代码已从8KB更新为128KB,更新发生在
f279894(“
read-cache
: make the index write buffer size 128K”,2021-02-18,Git v2.31.0-rc1 --
merge)。那里的理由是
do_write_index()
从1.02秒提高到0.72秒。由于我们的最终目标是使索引编写代码使用hashfile API,因此我们需要统一此缓冲区大小以避免性能退化。
由于这些缓冲区现在位于堆上,我们可以根据消费者的需求调整其大小。特别是,调用者调用
hashfd_throughput()
时期望在缓冲区刷新时报告进度指标。这些调用者更喜欢较小的8k缓冲区,以避免更新之间的大延迟,尤其是对于网络较慢的用户。当不使用进度指示器时,较大的缓冲区更可取。
通过在chunk-format API中添加一个新的
trace2
区域,我们可以看到“
git multi-pack-index write
”
(man)的写入部分在Linux机器上从约1.49秒降至约1.47秒。这些效果在其他文件系统上可能更加显著或减弱。