39

mapリストを並行して評価する代わりのものはありますか? 怠惰である必要はありません。

たとえば、すべてのコアを 100% にしますpmap :: (a -> b) -> [a] -> [b]pmap expensive_function big_list

4

2 に答える 2

44

はい、並列パッケージを参照してください:

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
于 2011-04-09T16:17:10.163 に答える
20

トムが説明したように自分で明示的な戦略を使用することに加えて、並列パッケージは以下もエクスポートparMapします。

 parMap :: Strategy b -> (a -> b) -> [a] -> [b]

ここで、戦略引数はのようなものrdeepseqです。

またparMap、par-monadパッケージにも含まれています(純粋なHaskellから出て、並列モナドに入る):

 parMap :: NFData b => (a -> b) -> [a] -> Par [b]

par-monadパッケージはここに文書化されています

于 2011-04-09T17:30:06.587 に答える