単純な操作を大規模なシーケンスに並列に効率的に適用するために、clojure を使用する方法を理解しようとしています。並列ソリューションを使用して、マシンの複数のコアを利用して速度を向上させたいと考えています。
pmap を partition-all と組み合わせて使用して、入力シーケンス内のすべてのアイテムの未来を作成するオーバーヘッドを削減しようとしています。残念ながら、partition-all は各パーティション seq の完全な評価を強制します。これにより、マシンで OutOfMemoryError が発生します。
(defn sum [vs]
(reduce + vs))
(def workers
(+ 2 (.. Runtime getRuntime availableProcessors)))
(let
[n 80000000
vs (range n)]
(time (sum vs))
(time (sum (pmap sum (partition-all (long (/ n workers)) vs)))))
大規模な入力セットに合計を適用し、シリアル実装のパフォーマンスを上回るにはどうすればよいですか?
解決
レデューサー ライブラリを指摘してくれた @Arthur Ulfeldt に感謝します。レデューサーを使用したソリューションを次に示します。このコードは、マルチコア マシンで実行したときに予想されるパフォーマンスの向上を示しています。(注:タイミングをより正確にするための関数になるようにvsを変更しました)
(require '[clojure.core.reducers :as r])
(let
[n 80000000
vs #(range n)]
(time (reduce + (vs)))
(time (r/fold + (vs)))