このページの内容

6 diff の性能上のトレードオフ

GNU diff は十分効率よく動作しますが、状況によっては、さらに速く動作させたり、より少ない変更の集合を出力させたりできます。

diff の性能を改善する方法の1つは、ファイルのコピーの代わりにハードリンクやシンボリックリンクを使うことです。diff は通常、同じファイルへの2つのハードリンクやシンボリックリンクを読み込む必要がありません。内容が同一であるはずだからです。たとえば、大きなディレクトリ階層をコピーし、そのコピーを少し変更して、「diff -r」で元の階層とコピーを頻繁に比較するとします。元のファイルが読み取り専用なら、ハードリンクやシンボリックリンクでコピーを作ると(たとえば GNU の「cp -lR」や「cp -sR」)、性能を大きく改善できます。コピー内のファイルを初めて編集する前に、そのリンクを切り、通常のコピーに置き換える必要があります。

ファイルの比較方法を変えるオプションでも、GNU diff の性能に影響を与えられます。性能には複数の側面があります。これらのオプションは、ある側面を改善する代わりに別の側面を損なったり、ある場合に改善する一方で別の場合には悪化させたりします。

GNU diff が変更された行を判定する方法は、常に最小に近い差分の集合を求めます。通常は実用上十分です。diff の出力が大きい場合は、ときどき差分の集合を小さくできる変更版のアルゴリズムを diff に使わせるとよいかもしれません。--minimal(-d)オプションがこれを行いますが、diff の動作が通常より遅くなることもあるため、既定の動作ではありません。

比較するファイルが大きく、小さな変更の集まりが各所に散らばっている場合、--speed-large-files オプションで diff のアルゴリズムに別の変更を加えられます。入力ファイルの変更密度が一定で低い場合、出力を変えずに比較を高速化します。そうでない場合、diff はより大きな差分の集合を出力するかもしれませんが、出力は依然として正しいものです。

通常、diff は最小の差分集合を求める前に、両ファイルで共通する先頭部分と末尾部分を取り除きます。これによって diff は速くなりますが、ときどき最小ではない出力になることがあります。--horizon-lines=lines オプションは、共通する先頭部分の最後の lines 行と末尾部分の最初の lines 行を diff が取り除くのを防ぎます。これによって diff が最小の出力を求める機会が増えます。

変更された連続行の一方の端にある行の並びと、もう一方の端のすぐ外側にある行の並びが同じだとします。diff コマンドは、どちらの同じ並びを hunk に含めるかを自由に選べます。この場合、diff は通常、隣接する hunk をまとめられるなら境界を移動し、または hunk の行をファイルの末尾側へ移動します。hunk をまとめると、出力の見た目がよくなる場合があります。