本文旨在介绍一种高效的文本差异分析工具的开发过程。该工具能够快速准确地比较两个文本文件的差异,对于软件开发、文档编辑等领域具有重要的应用价值。本文将从算法选择、实现细节、性能优化以及软件应用等方面进行详细阐述。
本文再次使用了Douglas McIlroy在20世纪70年代初编写的diff算法的实现,并参考了Eugene W. Myers在其论文中对该算法的描述。与以往不同的是,这次对多个diff进行了运行。首先,像以前一样对完整行进行diff,以揭示两个输入文件之间的差异。这些差异可以被分组到由相同行分隔的不同部分。这些部分可以被分类为文件A的删除、文件B的插入,或者两者都有。
有趣的部分是那些既有删除行又有插入行的部分。在这些部分中,可能存在行内的匹配文本,以及更小的真实差异。对于行的情况,所有差异都可以被认为是文件A的删除或文件B的插入。
对于这些部分,diff算法将在部分中的字符上运行。这次,寻找两个版本之间的相似之处。这些相似之处被记录下来,并以更柔和的颜色显示在输出中,从而突出显示差异。
下载的是一个WinForms应用程序,它将两个测试文件作为嵌入资源,默认加载。您还可以通过提供两个命令行参数的路径来diff任意两个文件。该应用程序运行所有必需的diff,并显示结果和一些计时测量。
在第一篇文章中,使用了WebBrowser控件来呈现输出。这次,创建了一个自定义控件,它继承自ScrollableControl。它并不复杂,但可以在10毫秒多一点的时间内渲染测试文件的输出。
删除的文本以红色显示,而文件A中匹配的文本以浅红色显示。同样,插入的文本是绿色的,而文件B中匹配的文本是浅绿色的。认为这很好地突出了实际的变化。
由于这是Lean and Mean竞赛的参赛作品,以下是一些指标:
Process.PeakWorkingSet64的变化始终在1.5 MB以下。
选择复制diff算法源代码来处理string[]和char[]的两种情况。这是因为算法中的热路径是等式运算符。可以使用泛型参数,用where T : IEquatable
保留了两个大的Int32数组,并在char diffs中重用它们。这很有帮助,因为在.NET中,内存分配和特别是收集是昂贵的。这也有助于在特定的测试用例中,两个char diffs所需的空间比第一个行diff少。