フォルダー内の数千のテキスト ファイル (サイズが ~400 KB の各ファイルに約 3000 行) を解析するのに問題があります。私はreadlinesを使ってそれらを読みました、
for filename in os.listdir (input_dir) :
if filename.endswith(".gz"):
f = gzip.open(file, 'rb')
else:
f = open(file, 'rb')
file_content = f.readlines()
f.close()
len_file = len(file_content)
while i < len_file:
line = file_content[i].split(delimiter)
... my logic ...
i += 1
これは、私の入力 (50,100 ファイル) からのサンプルに対して完全に正常に機能します。5,000 個を超えるファイルの入力全体を実行したところ、所要時間は直線的な増加にはほど遠いものでした。パフォーマンス分析を行う予定で、Cprofile 分析を行いました。入力が 7K ファイルに達すると、より多くのファイルにかかる時間が指数関数的に増加し、速度が低下します。
readlines の累積所要時間は次のとおりです。最初の -> 354 ファイル (入力からのサンプル) および 2 番目の -> 7473 ファイル (入力全体)
ncalls tottime percall cumtime percall filename:lineno(function)
354 0.192 0.001 **0.192** 0.001 {method 'readlines' of 'file' objects}
7473 1329.380 0.178 **1329.380** 0.178 {method 'readlines' of 'file' objects}
このため、私のコードにかかる時間は、入力が増加するにつれて線形にスケーリングされません。に関するいくつかのドキュメント ノートを読みましたが、これはファイル コンテンツ全体をメモリに読み込むため、またはに比べて一般的により多くのメモリを消費するとreadlines()
主張していました。readlines()
readline()
read()
私はこの点に同意しますが、ガベージコレクターはループの最後にメモリからロードされたコンテンツを自動的にクリアする必要があるため、いつでもメモリには現在処理されているファイルのコンテンツのみが含まれている必要があります。しかし、ここで落とし穴があります。誰かがこの問題についていくつかの洞察を与えることができます.
これはPythonガベージコレクターの固有の動作ですか、readlines()
それとも私の間違った解釈ですか。知ってよかった。
また、メモリと時間効率の良い方法で同じことを行ういくつかの代替方法を提案してください。ティア。