235

Pythonのパッケージの使い方を学ぼうとしているのですが、とmultiprocessingの違いがわかりません。との両方が非同期で実行されることに気付きました。では、いつどちらを使用する必要がありますか? そして、によって返された結果を取得するにはどうすればよいですか?map_asyncimapmap_asyncimapmap_async

このようなものを使用する必要がありますか?

def test():
    result = pool.map_async()
    pool.close()
    pool.join()
    return result.get()

result=test()
for i in result:
    print i
4

2 に答える 2

620

imap/imap_unorderedmap/には 2 つの重要な違いがありますmap_async

  1. 彼らがあなたが彼らに渡すイテラブルを消費する方法。
  2. 彼らが結果をあなたに返す方法。

mapiterable をリストに変換し (まだリストではない場合)、それをチャンクに分割し、それらのチャンクをPool. イテラブルをチャンクに分割すると、特にイテラブルが大きい場合に、プロセス間でイテラブル内の各アイテムを一度に 1 アイテムずつ渡すよりもパフォーマンスが向上します。ただし、イテラブルをチャンク化するためにリストに変換すると、リスト全体をメモリに保持する必要があるため、メモリ コストが非常に高くなる可能性があります。

imap与えられた iterable をリストに変換したり、チャンクに分割したりしません (デフォルト)。一度に反復可能な 1 つの要素を反復処理し、それぞれをワーカー プロセスに送信します。これは、イテラブル全体をリストに変換することによるメモリ ヒットが発生しないことを意味しますが、チャンキングがないため、大きなイテラブルのパフォーマンスが低下することも意味します。chunksizeただし、これはデフォルトの 1 より大きい引数を渡すことで軽減できます。

imap/imap_unorderedmap/のもう 1 つの大きな違いは、map_async/ をimap使用imap_unorderedすると、すべてのワーカーが終了するのを待つのではなく、準備ができたらすぐにワーカーから結果を受け取り始めることができることです。ではmap_asyncAsyncResultがすぐに返されますが、すべてのオブジェクトが処理されるまで、そのオブジェクトから実際に結果を取得することはできません。その時点で、map(mapは実際には として内部的に実装されていますmap_async(...).get()) と同じリストを返します。部分的な結果を取得する方法はありません。結果全体が得られるか、何も得られないかのいずれかです。

imapimap_unorderedどちらもイテラブルをすぐに返します。を使用imapすると、入力イテラブルの順序を維持しながら、準備が整うとすぐに結果がイテラブルから生成されます。を使用imap_unorderedすると、入力イテラブルの順序に関係なく、準備が整うとすぐに結果が得られます。だから、あなたがこれを持っているとしましょう:

import multiprocessing
import time

def func(x):
    time.sleep(x)
    return x + 2

if __name__ == "__main__":    
    p = multiprocessing.Pool()
    start = time.time()
    for x in p.imap(func, [1,5,3]):
        print("{} (Time elapsed: {}s)".format(x, int(time.time() - start)))

これは出力されます:

3 (Time elapsed: 1s)
7 (Time elapsed: 5s)
5 (Time elapsed: 5s)

p.imap_unorderedの代わりに使用すると、次のようにp.imap表示されます。

3 (Time elapsed: 1s)
5 (Time elapsed: 3s)
7 (Time elapsed: 5s)

p.mapまたはを使用するとp.map_async().get()、次のように表示されます。

3 (Time elapsed: 5s)
7 (Time elapsed: 5s)
5 (Time elapsed: 5s)

imapしたがって、 / imap_unorderedoverを使用する主な理由は次のmap_asyncとおりです。

  1. イテラブルが十分に大きいため、リストに変換するとメモリが不足したり、メモリを使いすぎたりします。
  2. すべての結果が完了する前に、結果の処理を開始できるようにしたいと考えています。
于 2014-10-23T04:51:41.540 に答える