2017-10-13 102 views
0

forループを高速化するための並列処理を統合したい。Python:Joblibの並列処理によりコード実行が遅くなる

ただし、私のコードが遅く実行されたことに気付きました。私がjoblibを単純な関数で乱数のリストに使用している以下の例を参照してください。 なしで、並列処理はより速く実行され、となります。

何が起こっているかについての洞察はありますか?

def f(x): 
    return x**x 

if __name__ == '__main__': 
    s = [random.randint(0, 100) for _ in range(0, 10000)] 


    # without parallel processing 
    t0 = time.time() 
    out1 = [f(x) for x in s] 
    t1 = time.time() 
    print("without parallel processing: ", t1 - t0) 

    # with parallel processing 
    t0 = time.time() 
    out2 = Parallel(n_jobs=8, batch_size=len(s), backend="threading")(delayed(f)(x) for x in s) 
    t1 = time.time() 
    print("with parallel processing: ", t1 - t0) 

私は次の出力を取得しています:

without parallel processing: 0.0070569515228271484 
with parallel processing:  0.10714387893676758 
+0

並列処理があるため、より複雑な設定の追加のオーバーヘッドを必要とします。通常は、完了するまでにマイクロ秒かかるタスクを並列化したくありません。 – Muposat

+0

さらに複雑なファジーマッチング関数でも試しましたが、まだまだ時間がかかりました。 –

+0

[単純な並列化されたコードはPythonの単純なループよりもずっと遅いのですがなぜですか?](https://stackoverflow.com/questions/46727090/why-is-the-following-simple-parallelized-code-much-slow-a-simple-loop-in) – user3666197

答えて

0

パラメータbatch_size=len(s)を効果的に各プロセスにSジョブのバッチを与えると言います。つまり、8つのスレッドを作成した後、すべてのワークロードを1つのスレッドにすることを意味します。

また、測定可能な利点を得るために作業負荷を増やすこともできます。私はtime.sleep遅延を使用することを好む:並列処理なし

def f(x): 
    time.sleep(0.001) 
    return x**x 

out2 = Parallel(n_jobs=8, 
       #batch_size=len(s), 
       backend="threading")(delayed(f)(x) for x in s) 

:並列処理と11.562264442443848

:1.412865400314331

+0

敬意をもって、卿はf()に睡眠を加えると、アムダールの法則に関して誤った錯覚を作り出しています。 [PARALLEL] -fraction(ここでは)は非常に小さいので、[SERIAL]パートが支配的であり、sleep()を[PARALLEL]セクションに追加しても処理性能は向上しませんが、[ SER] + [PAR]/1v/s [SER] + [PAR]/Nである。 [PAR] -Setupと[PAR] -Terminateオーバーヘッドのコストは、sleep()を追加することでよりマスクされます。 – user3666197

関連する問題