web-dev-qa-db-ja.com

delayed()関数は何をしますか(Pythonでjoblibを使用する場合)

documentation を読みましたが、次の意味がわかりません:The delayed function is a simple trick to be able to create a Tuple (function, args, kwargs) with a function-call syntax.

次のように、操作するリスト(allImages)を反復処理するために使用しています。

def joblib_loop():
    Parallel(n_jobs=8)(delayed(getHog)(i) for i in allImages)

これにより、HOGの機能が必要なように(および8つのコアすべてを使用した速度向上で)返されますが、実際に何を行っているのかわかりません。

私のPython知識はせいぜい大丈夫です、そして私は基本的な何かを見逃している可能性が非常に高いです。

31
orrymr

代わりに単に書いた場合に何が起こるかを見ると、おそらく物事はより明確になるでしょう

_Parallel(n_jobs=8)(getHog(i) for i in allImages)
_

方法Python=、work、getHog(i) for i in allImagesは、各要素が既に評価されているリストを作成します。これは、リストがgetHogオブジェクトに渡されるまでにすべてのParallel呼び出しが既に返されており、Parallelを並列実行するために何も残っていないことを意味します!私たちが今いるスレッドで、すでに順番に行われています。

したがって、delay実行する必要があるa。)呼び出したい関数とb 。)関数を呼び出したいが、実際に関数を既に実行していない引数。

これは、delayedがわかりやすい構文で便利に行うことです。後で呼び出しfoo(2, g=3)を「保持」したい場合は、単にdelayed(foo)(2, g=3)を呼び出すと、タプル_(foo, [2], {g: 3})_が返され、他の誰かが実行できる状態になります。


あなたの例では、一言で言えば、次のことが起こります。

  1. delayed(getHog)(i)のリストを作成しました

  2. これらのdelayed(getHog)(i)のそれぞれは、タプル_(function, args, kwargs)_(ドキュメントで読むように)を返します。この場合は、タプル_(getHog, [i], {})_です。

  3. 以前に構築したParallelオブジェクトは、リスト内の各要素に対して新しいスレッドを作成し、それらにタプルを配布します

  4. これらの新しいスレッドのそれぞれで、リスト要素の1つを実行します。2番目と3番目の要素を引数el[0](*el[1], **el[2])またはfunction(*args, **kwargs)としてアンパックして、タプルの最初の要素を呼び出します。この場合、getHog(i)が呼び出されます。
28
Nearoo