何らかの理由で1行しかない巨大な(250 MB)テキストファイルを解析しなければならないため、試したすべてのテキストエディタ(Notepad ++、Visual Studio、Matlab)がロードに失敗します。したがって、私はそれを1枚ずつ読んで、そして(#
で始まる)論理行が完全に読まれるたびにそれを解析:予期せぬパフォーマンスの低下
f = open(filename, "rt")
line = ""
buffer = "blub"
while buffer != "":
buffer = f.read(10000)
i = buffer.find('#')
if i != -1: # end of line found
line += buffer[:i]
ProcessLine(line)
line = buffer[i+1:] # skip the '#'
else: # still reading current line
line += buffer
これは合理的にうまく機能、しかし、ラインが私のバッファよりも短いこと、起こるかもしれませんこれは私にラインをスキップさせるでしょう。だから私はループをループに置き換えました。
while buffer != "":
buffer = f.read(10000)
i = buffer.find('#')
while i != -1:
pixels += 1
line += buffer[:i]
buffer = buffer[i+1:]
ProcessLine(line)
i = buffer.find('#')
line += buffer
これはやっています。しかし、これは少なくとも100倍遅く、大きなファイルを読むのに無用です。私は実際には見えません、どうしてこのようなことが起こるか、私は内部のループを持っていますが、ほとんどの場合、それは一度だけ繰り返されます。また、私はおそらく、パフォーマンスが半減したらどういうわけか理解できたバッファー(buffer = buffer[i+1:]
)をコピーしていますが、これがどのようにして100倍遅くなるかわかりません。
注:私の(論理)行は約27.000バイトです。したがって、私のバッファが10.000バイトであれば、最初の実装で行をスキップすることは決してありません。しかし、これはパフォーマンスに影響を与えないように見えますが、第2実装の内部ループが最大で1回評価されても、パフォーマンスはまだひどいです。
私は見逃しているボンネットの下で何が起こっていますか?
最初のバージョンでは、10.000に1回だけ分割します。2番目の分割では、何回もチャンクに入るので、Xは10.000あたりの平均数です。バイト。それがX倍遅いなら、あなたの答えはここにあります。 – Andrey
いいえ、それはできません。私のテストケースでは、#〜27.000文字毎に#があります。バッファの長さが30.000の場合、これらのうちのいくつかをスキップします。10.000の場合は、すべて取得します。どちらの場合も、2番目の実装でのパフォーマンスは恐ろしいものです。私はこれをメモとして加えました。 – JonathanK
250MBは少量のデータです。なぜあなたはそれをすべてメモリに読んでそこで処理しないのですか? OSファイルの読み込みバッファを使用しても、はるかに高速になります。 – advance512