このコマンドは、8コアのMac OSXで実行しています。
for i in $(cat file1);do grep "$i" file2; done > output.txt
私のfile2は900万行なので、時間がかかります。すべてのコアを使用してジョブを分割し、すべてをより高速に実行することは可能ですか?
処理を高速化する方法は他にもあります。grep -f file1 file2 >output.txt
を使用します。
Gnu parallelを使用することもできます: http://www.gnu.org/software/parallel/parallel_tutorial.html
grep -F -f needles.txt haystack.log
はあなたが望むものです。
-F
完全な正規表現が必要ない場合は、grepで単純なパターンマッチングを使用します。これは非常に高速化される傾向があります。探しているものによっては、正規表現が必要ない場合もあるため、より単純なコードをより高速に実行できるという利点も得られる可能性があります。
-f
はあなたが探しているパターンのファイルです。したがって、Nパターンに対して完全なNスキャンを実行する代わりに、1回のパスで実行できます。これは、RAMに収まらないほど大きいファイルの大幅な高速化でもあります。
検索しているファイルを高速ディスクに置きます。 grepは非常に直線的な方法でスキャンを実行するため、SSDは必ずしもここでの答えではありません。これは通常の回転ディスクでは問題なく、アレイがある場合は特に高速です。
2つのスイッチの組み合わせに加えて、HDDの速度により、grepを非常に高速にすることができます。データの反復性が非常に高い(圧縮性が高い)場合は、データをgzipで保存し、zgrepで検索することをお勧めします。これは、ストレージが特に高速でない場合にさらに役立ちます。
データがファイルにどのように入るかについて責任がある場合は、物事を小さくしてください。構造化のために多くのスペースを浪費しないでください。情報を含まないデータ(UUID内の-、またはXMLタグ間のスペースと改行を考えてください)を取り出すと、ログが小さくなり、ディスクの読み取り時間と解析の両方が可能になります時間が短くなります。
場合によっては、実際には二重解析を実行する方が高速です。これはデータに大きく依存します。たとえば、解析が複雑なデータを探しているが、別の解析しやすい式で簡単に識別できる少量のエントリでしか発生しない場合は、簡単な式の最初のパスを実行します。これにより、低速/複雑な式を実行するために必要なデータが削減されます。
これらが役に立たない場合は、split -l
ファイルを作成し、grep
をparallel
で実行します。複数のファイルを分割/書き込みしてから、複数のプロセスが同じディスクを同時に使用しようとする合計時間は、ジョブにかかる合計時間に悪影響を与える可能性があることに注意してください。大きなファイルを複数のディスク上の小さなファイルに分割できる場合は、そうです。そうすれば、検索がおそらく高速になります。
私がよく見かける間違いの1つは、分割ファイルをramdiskに配置しようとすることです。それはあなたがひどくキャッシュをしていることです。 OSは、ファイル全体ではなく、実際に作業しているものをキャッシュするために同じ量のRAMを使用してより良い仕事をする可能性があります。
また、さまざまなシナリオで遊んでいるときにCPUとディスクのアクティビティを監視し、「ボトルネック」と「飽和」の違いを学習する必要があります。
http://www.gnu.org/software/parallel/man.html#EXAMPLE:-Grepping-n-lines-for-m-regular-expressions に基づく
parallel -k parallel --pipepart --block 100M -a file2 -k grep {} :::: file1
よりシンプルでおそらくより速い:
parallel -j0 -k grep {} file2 :::: file1