Python 2.7 で 800 GB の xml ファイルを読み取り、etree 反復パーサーで解析しています。
現在、open('foo.txt')
バッファリング引数なしで使用しています。これが取るべきアプローチなのか、バッファリング引数を使用するのか、io.BufferedReader、io.open、io.TextIOBase などの io から何かを使用するのか、少し混乱しています。
正しい方向へのポイントは大歓迎です。
Python 2.7 で 800 GB の xml ファイルを読み取り、etree 反復パーサーで解析しています。
現在、open('foo.txt')
バッファリング引数なしで使用しています。これが取るべきアプローチなのか、バッファリング引数を使用するのか、io.BufferedReader、io.open、io.TextIOBase などの io から何かを使用するのか、少し混乱しています。
正しい方向へのポイントは大歓迎です。
標準open()
関数は、デフォルトですでにバッファリングされたファイルを返します (プラットフォームで利用可能な場合)。通常は完全にバッファリングされるファイル オブジェクト用。
通常、ここでは Python がこれを C stdlib 実装に任せることを意味します。( Windows では UTF-16 ファイル名をサポートするために)fopen()
呼び出しを使用します。これは、ファイルのデフォルトのバッファリングが選択されることを意味します。wfopen()
Linux では 8kb になると思います。XML 解析のような純粋な読み取り操作の場合、このタイプのバッファリングはまさにあなたが望むものです。
によって行われる XML 解析iterparse
は、ファイルを 16384 バイト (16kb) のチャンクで読み取ります。
バッファサイズを制御したい場合は、buffering
キーワード引数を使用してください:
open('foo.xml', buffering=(2<<16) + 8) # buffer enough for 8 full parser reads
これにより、デフォルトのバッファサイズが上書きされます(ファイルブロックサイズまたはその倍数に一致すると予想されます)。この記事によると、読み取りバッファーを増やすと効果があり、予想される読み取りブロック サイズの 4 倍以上のサイズに 8 バイトを加えたサイズを使用すると、読み取りパフォーマンスが向上します。上記の例では、ElementTree の読み取りサイズの 8 倍に設定しました。
このio.open()
関数はオブジェクトの新しい Python 3 I/O 構造を表しており、I/O はクラス タイプの新しい階層に分割され、柔軟性が向上しています。その代償は、より間接的であり、データが通過しなければならないレイヤーが増え、OS に任せるのではなく、Python C コード自体がより多くの作業を行うことです。
のパフォーマンスが向上するかどうかを試してみることができio.open('foo.xml', 'rb', buffering=2<<16)
ます。rb
モードで開くと、io.BufferedReader
インスタンスが表示されます。
使用したくないio.TextIOWrapper
; 基礎となる expat パーサーは、XML ファイルのエンコーディング自体をデコードするため、生データを必要とします。追加のオーバーヘッドが追加されるだけです。r
代わりに (テキストモード)で開くと、このタイプになります。
を使用io.open()
すると、より柔軟で豊富な API が得られますが、基礎となる C ファイル オブジェクトはopen()
の代わりに を使用して開かfopen()
れ、すべてのバッファリングは Pythonio.BufferedIOBase
実装によって処理されます。
あなたの問題は、ファイルの読み取りではなく、この獣の処理にあると思います。いずれにせよ、800GB のファイルを読み取ると、ディスク キャッシュはほとんど消費されます。
遅延関数を試しましたか?:Pythonで大きなファイルを読み取るための遅延メソッド?
これはすでにあなたの質問に答えているようです。ただし、このメソッドを使用してデータをデータベースに書き込むことを検討します。mysqlは無料です:http : //dev.mysql.com/downloads/、NoSQLも無料であり、800GBの書き込みを含む操作にもう少し調整される可能性がありますデータ、または同様の量:http ://www.oracle.com/technetwork/database/nosqldb/downloads/default-495311.html
私はそのような壮大な xml ファイルでそれを試したことはありませんが、前回大きな (そして比較的単純な) xml ファイルを処理しなければならなかったときは、sax パーサーを使用しました。
基本的に、「イベント」ごとにコールバックを提供し、必要なデータを保存するためにそれを任せます。一度にすべてを読み取る必要がないように、開いているファイルを指定できます。