`git diff –patience`和`git diff –histogram`有什么区别?
这个较早的问题要求提供4种不同的Git diff策略之间的差异,但唯一解释的差异是myers
和patience
之间的差异,这在其他地方很好解释。
histogram
策略如何工作? 它与patience
什么区别? git-diff手册页只是说它“把耐心algorithm延伸到”支持低出现的共同元素“。 其他网页提到它更快,它来自JGit,但是它们没有解释它的algorithm或结果在哪里或如何与patience
不同 。
在哪里可以find与patience
algorithm相关的histogram
algorithm的描述 ,与Bram Cohen对patience
algorithm的原始描述具有相同的细节水平?
(如果只是执行性能问题,没有任何情况会产生不同的结果,为什么它不是作为patience
的新后端来实现?
这个直方图策略是在git 1.7.7(2011年9月)中引入的,具有以下描述(如OP所述)
“
git diff
”学到了一个“--histogram
”选项来使用--histogram
不同的差异生成机器,这可能会带来更好的性能。
JGit包含src/org/eclipse/jgit/diff/HistogramDiff.java
和tst/org/eclipse/jgit/diff/HistogramDiffTest.java
这里的描述相当完整:
HistogramDiff
Bram Cohen的耐心差异algorithm的扩展forms。
这个实现是通过使用Bram Cohen博客中概述的4个规则得出的 ,然后进一步扩展到支持低出现率的通用元素。
该algorithm的基本思想是为序列A的每个元素创build出现的直方图 。 然后依次考虑序列B的每个元素。 如果该元素也存在于序列A中,并且具有较低的出现次数,则该位置被视为最长公共子序列(LCS)的候选者。
在B的扫描完成之后,select发生次数最less的LCS作为分割点。 该区域在LCS周围分裂,并且该algorithmrecursion地应用于LCS之前和之后的部分。通过始终select出现次数最less的LCS位置,只要两个序列之间存在唯一的公共元素,该algorithm的行为与Bram Cohen的耐心差异完全相同。
如果不存在唯一元素,则select最低发生元素 。
这提供了比标准Myers'OO(ND)
algorithm产生的更简单的可读差异。为了防止algorithm运行
O(N^2)
,直方图桶中唯一元素的数量上限由#setMaxChainLength(int)
configuration。
如果序列A具有比这多个散列到相同散列桶的元素多的algorithm,则algorithm将该区域传递给#setFallbackAlgorithm(DiffAlgorithm)
。
如果未configuration故障预置algorithm,则该区域将作为replace编辑发出。在扫描序列B的过程中,即使在两个序列之间是共同的,对于LCS匹配位置也不会考虑发生超过
#setMaxChainLength(int)
倍的A的任何元素。 这限制了序列A中必须考虑查找LCS的位置数量,并有助于保持较低的运行时间界限。只要
#setMaxChainLength(int)
是一个小常量(如64),algorithm运行在O(N * D)
时间,其中N
是input长度的总和,D
是所得EditList
中编辑的数量。
如果提供的SequenceComparator
具有良好的散列函数,MyersDiff
即使其理论运行时间相同,该实现通常也会执行MyersDiff
。这个实现有一个内部限制,可以防止处理超过268,435,456(2 ^ 28)个元素的序列
请注意,这种algorithm已经用于pack_check,早在2006年(git 1.3) ,用于git-verify-pack -v
。 它被重用在git 1.7.7中的索引包
提交8c912ee实际上介绍了--histogram
差异:
将JGit的HistogramDiffalgorithm转换为C.粗数字(TODO)表明它比它的 –
--patience
表亲以及默认的Meyersalgorithm更快。这个实现已经被改写为使用结构体和指针,而不是位掩码,从而消除了JGit的
2^28
行限制 。为了方便起见,我们还使用
xdiff
的默认哈希表实现(xdl_hash_bits()
和XDL_HASHLONG()
)。
提交8555123(git 1.7.10,2012年4月)补充说:
8c912ee(教 –
diff
,2011-07-12)声称直方图差异--histogram
和耐心更快。我们已经整合了一个性能testing框架,因此添加一个testing来比较真正的“
log -p
”工作负载中执行的各种diff任务。
这确实表明,直方图差异稍微击败迈尔斯,而耐心比其他人慢得多。
最后, 提交07ab4de(git 1.8.2,2013年3月)添加
config:引入diff.algorithmvariables
一些用户或项目比其他用户更喜欢不同的algorithm,例如对迈尔斯或类似的耐心。
但是,每次使用diff时指定适当的参数是不切实际的。 而且,创build一个别名与基于diff的其他工具(例如git-show
)并不能很好地兼容。因此,需要能够设置特定algorithm的configurationvariables。
现在,这四个值被接受:
- '
myers
'(其效果与不设置configurationvariables相同),- '
minimal
',- “
patience
”和- '
histogram
'。
Commit 07924d4同时添加了--diff-algorithm
命令行选项。
正如OP Stuart P. Bentley 在评论中提到的那样 :
你可以configurationGit默认使用直方图 :
git config --global diff.algorithm histogram
更新:Git 2.12(2017年第1季度)将会退出在某些特定情况下出现灾难性性能问题的“快速哈希”。
见Jeff King( peff
)的 提交1f7c926 (2016年12月1日) 。 (由Junio C gitster
合并- gitster
-在承诺731490b ,2016年12月19日)
xdiff
:dropXDL_FAST_HASH
xdiff
代码散列diff的两边的每一行,然后比较这些散列以查找重复项 。 整体性能取决于我们可以计算散列的速度,也取决于我们看到多less散列冲突。
XDL_FAST_HASH
的思想是加快哈希计算。
但生成的哈希碰撞行为更差。 这意味着在某些情况下,它的速度差异很大(在git.git
上运行“git log -p
”git.git
提高git.git
~8%
),但在其他情况下,速度可能会减慢。 一个病理案例超过了100倍的放缓 。可能有一个更好的散列函数,涵盖了两个属性,但与此同时,我们最好使用原始散列。 常见病例稍慢,但病例较less,