非常に大きなテキストファイル(27GB)が1つあり、より適切なサイズ(500MB-2GB)のファイルが複数ある2番目のデータベースで重複している行を削除して小さくしようとしています。私はいくつかの関数型コードを持っていますが、私が疑問に思っているのは、このコードを最適化してより高速な人間の時計時間を実行する方法はありますか?現時点では、1.5GBの入力と500MBのフィルターを使用した小規模なテスト実行では、これが完了するまでに75秒かかります。
私はこのアイデアを何度も繰り返してきましたが、これは現在のところ最適です。誰かがフィルターのより良い論理構造を作成するためのアイデアを持っているなら、それを聞きたいです。過去の試みはすべてこれよりも悪いものでした。 :フィルターをセットにロードし、入力を循環して重複を検索し(これの約半分の速度)、入力をセットにロードし、difference_updateを介してフィルターを実行します(これとほぼ同じ速度ですが、逆のことも行います)私が欲しかったのは)、入力とフィルターの両方をチャンクのセットにロードし、セットの違いを実行することです(これは、フィルターが小さければ(多分?)うまくいくので、それらを分割する必要もありませんでした。 )。
だから、これらは私が試したすべてのものです。これらのプロセスはすべてCPUで最大になり、最終バージョンは約25〜50%のディスクI / Oで実行され、フィルターと出力は1つの物理ディスクにあり、入力は別の物理ディスクにあります。私はデュアルコアを実行していますが、この特定のスクリプトをスレッド化できるかどうかわかりません。これまでマルチスレッド化を行ったことはありません。その可能性がある場合は、正しい方向に向けてください。
データに関する情報!前に述べたように、入力はフィルターより何倍も大きくなります。重複の割合はごくわずかだと思います。データは行単位であり、すべて20ASCII文字未満の長さです。ファイルはすべてソートされています。
一意の入力行が行の大部分、次に一意のフィルター、次に重複するという予想に基づいて、3つの論理ステートメントの順序を既に変更しました。これは、重複がまったくない「最良の」場合です。約10%の時間を節約できました。
助言がありますか?
def sortedfilter(input,filter,output):
file_input = open(input,'r')
file_filter = open(filter,'r')
file_output = open(output,'w')
inline = file_input.next()
filterline = file_filter.next()
try:
while inline and filterline:
if inline < filterline:
file_output.write(inline)
inline = file_input.next()
continue
if inline > filterline:
filterline = file_filter.next()
continue
if inline == filterline:
filterline = file_filter.next()
inline = file_input.next()
except StopIteration:
file_output.writelines(file_input.readlines())
finally:
file_filter.close()
file_input.close()
file_output.close()