2017-12-15 21 views
0

Pythonオブジェクトのリストにロードするのに多くの時間(約30分)かかるJSONファイルが数多く(約30万件)あるとします。プロファイリングは、実際にはファイルへのアクセスではなく、ほとんどの時間を要するデコードであることを明らかにしました。これらのファイルを変換できる形式はありますか?これはオブジェクトのPythonリストにはるかに高速に読み込むことができますか?Pythonで大量のJSONのようなデータを素早くデコードしてください

私の試み:私は(別名Googleのプロト COL BUF FERS)いるProtobufにファイルを変換しますが、私は本当に小さなファイル(元のサイズの〜20%に減少)、時間を持っていてもそれらをロードすると、それを劇的に向上させることはできませんでした(それらすべてをロードするのに20分以上を要します)。

+0

['MessagePack'](https://msgpack.org/)[[msgpack-python'](https://github.com/msgpack/msgpack-python))を試してください。一般的なデータ構造の場合よりもはるかに高速になることはありません。もちろん、あなたのデータをあなたのデータに合わせて調整して、最後の1オンスのパフォーマンスを絞り出すことができますが、その時点で私の戦略を最初に思い浮かべます。 – zwer

答えて

2

あなたが望むだけの負荷時間をカットしない可能性があるので、変換に間違った方向を見ている可能性があります。デコードに多くの時間がかかる場合、JSONデコーダが本当にひどく書かれていないと仮定すると、おそらく他のフォーマットからかなりの時間がかかるでしょう。私は、標準のライブラリ関数がうまく実装されていると仮定しています.JSONはデータストレージの速度的なフォーマットではありません。

あなたが使用していると仮定するデフォルトのCPython実装ではなく、PyPyでプログラムを実行してみることができます。 PyPyは実行時間を大幅に短縮する可能性があります。それはより速いJSONモジュールを持っていて、あなたのプログラムを高速化するかもしれないJITを使用します多くの

Python 3を使用している場合は、ProcessPoolExecutorを使用して、ファイルの読み込みとデータの直列化/デコードを同時に実行することもできます。並行性の程度を試す必要がありますが、開始点はCPUコアの数です(半分または2倍にすることができます)。あなたのプログラムがI/Oをたくさん待っているならば、より高い並行性を実行しなければなりません.I/Oの程度が小さければ並行性を減らすことができます。各エグゼキュータを書き込んでPythonオブジェクトにデータをロードし、単にそれらを返すようにすると、読み込み時間を大幅に短縮できるはずです。 GILではスレッドが機能しないため、プロセス駆動型のアプローチを使用する必要があります。

また、faster JSON libraryを使用すると、最適なケースで2倍または3倍の実行時間を短縮できます。実世界のユースケースでは、スピードアップはおそらく小さくなります。 代替のCFF​​Iインプリメンテーションを使用し、CPythonプログラムでは動作しないため、PyPyには良いJSONモジュールがあるため、これらはPyPyでは動作しない可能性があります。

+0

'ProcessPoolExecutor'を使うという提案は、私にとって非常に貴重なものです。ProtoBuf + 'ProcessPoolExecutor'の実行時間は現在わずか5分です。他の提案(特にPyPy)に関しては、後で試してみる必要があります。今のところ十分です。ああ、ありがとうございます:) – Matmarbon

0

ujsonを試してみてください。かなり速いです。

「デコードにはほとんどの時間がかかります」とは、「Pythonオブジェクトをビルドすることは常に時間がかかる」と見ることができます。あなたは本当にこれらすべてのことをいつもRAMのPythonオブジェクトとして必要としていますか?それはかなり多くなければならない。

たとえば、適切なデータベースを使用することを検討したいと思います。そのようなサイズのデータ​​を照会する。

別の種類の一括処理が必要な場合(例:統計や行列の処理については、pandasをご覧ください。

関連する問題