map
リストを並行して評価する代わりのものはありますか? 怠惰である必要はありません。
たとえば、すべてのコアを 100% にしますpmap :: (a -> b) -> [a] -> [b]
。pmap expensive_function big_list
map
リストを並行して評価する代わりのものはありますか? 怠惰である必要はありません。
たとえば、すべてのコアを 100% にしますpmap :: (a -> b) -> [a] -> [b]
。pmap expensive_function big_list
はい、並列パッケージを参照してください:
ls `using` parList rdeepseq
rdeepseq
戦略を介してリストの各要素を並行して評価します。parListChunk
要素が安すぎて各要素を並行して評価するメリットが得られない場合は、適切なチャンク値を使用して を使用すると、パフォーマンスが向上する可能性があることに注意してください (各要素のスパークを節約できるため)。
編集:あなたの質問に基づいて、これが答えである理由を説明する必要があると思います。それは Haskell が怠け者だからです! ステートメントを検討してください
let bs = map expensiveFunction as
何も評価されていません。これで、マップするサンクが作成されましたexpensiveFunction
。では、どのように並行して評価するのでしょうか?
let bs = map expensiveFunction as
cs = bs `using` parList rdeepseq
今後の計算ではリストを使用しないbs
でください。代わりにcs
リストを使用してください。IOW、並列マップは必要ありません。通常の (遅延) マップと並列評価戦略を使用できます。
編集: そして、十分に見回すと、ここで示したものを実行するparMap関数が 1 つのヘルパー関数にラップされていることがわかります。
あなたのコメントに応えて、以下のコードは機能しませんか? わたしにはできる。
import Control.Parallel.Strategies
func as =
let bs = map (+1) as
cs = bs `using` parList rdeepseq
in cs
トムが説明したように自分で明示的な戦略を使用することに加えて、並列パッケージは以下もエクスポートparMap
します。
parMap :: Strategy b -> (a -> b) -> [a] -> [b]
ここで、戦略引数はのようなものrdeepseq
です。
またparMap
、par-monadパッケージにも含まれています(純粋なHaskellから出て、並列モナドに入る):
parMap :: NFData b => (a -> b) -> [a] -> Par [b]
par-monadパッケージはここに文書化されています。