6つの大きなファイルがあり、それぞれにpickle関数を使用してハードディスクに保存した辞書オブジェクトが含まれています。それらすべてを順番にロードするのに約600秒かかります。プロセスをスピードアップするために、それらすべてを同時にロードし始めたいと思います。それらがすべて同じサイズであるとすると、代わりに100秒でロードしたいと思います。マルチプロセッシングとapply_asyncを使用して、それぞれを個別にロードしましたが、シーケンシャルのように実行されます。これは私が使用したコードであり、機能しません。コードはこれらのファイルのうち3つ用ですが、6つでも同じです。IOが制限されていないことを確認するために、3番目のファイルを別のハードディスクに置きました。
def loadMaps():
start = timeit.default_timer()
procs = []
pool = Pool(3)
pool.apply_async(load1(),)
pool.apply_async(load2(),)
pool.apply_async(load3(),)
pool.close()
pool.join()
stop = timeit.default_timer()
print('loadFiles takes in %.1f seconds' % (stop - start))
コードが主にIOによって制限されており、ファイルが複数のディスク上にある場合は、スレッドを使用してコードを高速化できる可能性があります。
import concurrent.futures
import pickle
def read_one(fname):
with open(fname, 'rb') as f:
return pickle.load(f)
def read_parallel(file_names):
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = [executor.submit(read_one, f) for f in file_names]
return [fut.result() for fut in futures]
PythonはIOを実行するときに一貫して解放するため、GILはIO操作を強制的にシリアル化して実行しません。
代替案に関するいくつかの意見:
multiprocessing
複数のプロセスでの作業を保証する一方で(したがってGILを使用せずに)、サブプロセスとメインプロセスの間でコンテンツを転送する必要があり、追加の時間がかかるため、役立つ可能性はほとんどありません。
asyncio
非同期ファイルシステムアクセスをネイティブにサポートしていないため(また、一般的なOSもサポートしていないため)、まったく役に立ちません。スレッドでエミュレートできますが、効果は上記のコードと同じですが、セレモニーがはるかに多くなります。
どちらのオプションも、6つのファイルの読み込みを6倍高速化することはできません。少なくとも一部の時間は、GILによってシリアル化される辞書の作成に費やされていることを考慮してください。起動を本当にスピードアップしたい場合は、辞書全体を事前に作成してファイル内データベースに切り替えるのではなく、辞書を使用してコンテンツへのアクセスをキャッシュすることをお勧めします。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加