Python 3: プールはマップに渡されたデータの元の順序を保持しますか? 質問する

Python 3: プールはマップに渡されたデータの元の順序を保持しますか? 質問する

4 つのスレッド間でワークロードを分散し、結果が(入力の順序に従って)順序どおりに保たれているかどうかをテストするための小さなスクリプトを作成しました。

from multiprocessing import Pool
import numpy as np
import time
import random


rows = 16
columns = 1000000

vals = np.arange(rows * columns, dtype=np.int32).reshape(rows, columns)

def worker(arr):
    time.sleep(random.random())        # let the process sleep a random
    for idx in np.ndindex(arr.shape):  # amount of time to ensure that
        arr[idx] += 1                  # the processes finish at different
                                       # time steps
    return arr

# create the threadpool
with Pool(4) as p:
    # schedule one map/worker for each row in the original data
    q = p.map(worker, [row for row in vals])

for idx, row in enumerate(q):
    print("[{:0>2}]: {: >8} - {: >8}".format(idx, row[0], row[-1]))

私の場合、これは常に次の結果になります:

[00]:        1 -  1000000
[01]:  1000001 -  2000000
[02]:  2000001 -  3000000
[03]:  3000001 -  4000000
[04]:  4000001 -  5000000
[05]:  5000001 -  6000000
[06]:  6000001 -  7000000
[07]:  7000001 -  8000000
[08]:  8000001 -  9000000
[09]:  9000001 - 10000000
[10]: 10000001 - 11000000
[11]: 11000001 - 12000000
[12]: 12000001 - 13000000
[13]: 13000001 - 14000000
[14]: 14000001 - 15000000
[15]: 15000001 - 16000000

質問: では、各関数Poolの結果を に格納するときに、元の入力の順序が本当に維持されるのでしょうか?mapq

サイドノート: 複数のワーカー間で作業を並列化する簡単な方法が必要なため、これを質問しています。場合によっては、順序は関係ありません。ただし、q順序付けられたデータに依存する追加の削減関数を使用しているため、結果 ( など) を元の順序で返す必要がある場合もあります。

パフォーマンス: 私のマシンでは、この操作は単一プロセスでの通常の実行よりも約 4 倍高速です (4 つのコアがあるため、予想どおり)。さらに、実行時には 4 つのコアすべてが 100% 使用されます。

ベストアンサー1

Pool.map結果は順序付けされます。順序付けが必要な場合は問題ありませんが、そうでない場合はPool.imap_unordered便利な最適化となるかもしれません。

結果を受け取る順序はPool.map固定されていますが、計算される順序は任意であることに注意してください。

おすすめ記事