以下代码基本上只允许您并行执行类似(function(range n))的操作.
(experiment-with-agents 10000 10 #(filter prime? %))
Run Code Online (Sandbox Code Playgroud)
例如,这可以使用10个代理查找0到10000之间的素数.
(experiment-with-futures 10000 10 #(filter prime? %))
Run Code Online (Sandbox Code Playgroud)
与期货一样.
现在的问题是,期货的解决方案不会随着更多的期货而更快地运行.例:
; Futures
(time (experiment-with-futures 10000 1 #(filter prime? %)))
"Elapsed time: 33417.524634 msecs"
(time (experiment-with-futures 10000 10 #(filter prime? %)))
"Elapsed time: 33891.495702 msecs"
; Agents
(time (experiment-with-agents 10000 1 #(filter prime? %)))
"Elapsed time: 33048.80492 msecs"
(time (experiment-with-agents 10000 10 #(filter prime? %)))
"Elapsed time: 9211.864133 msecs"
Run Code Online (Sandbox Code Playgroud)
为什么?我做错了什么(可能是Clojure的新手,只是玩弄东西^^)?因为我认为期货在这种情况下实际上是首选的.
资源:
(defn setup-agents
[coll-size num-agents]
(let [step (/ coll-size num-agents)
parts (partition step (range coll-size))
agents (for [_ (range num-agents)] (agent []) )
vect (map #(into [] [%1 %2]) agents parts)]
(vec vect)))
(defn start-agents
[coll f]
(for [[agent part] coll] (send agent into (f part))))
(defn results
[agents]
(apply await agents)
(vec (flatten (map deref agents))))
(defn experiment-with-agents
[coll-size num-agents f]
(-> (setup-agents coll-size num-agents)
(start-agents f)
(results)))
(defn experiment-with-futures
[coll-size num-futures f]
(let [step (/ coll-size num-futures)
parts (partition step (range coll-size))
futures (for [index (range num-futures)] (future (f (nth parts index))))]
(vec (flatten (map deref futures)))))
Run Code Online (Sandbox Code Playgroud)
你会因为for产生一个懒惰的序列而被绊倒experiment-with-futures.特别是这段代码:
(for [index (range num-futures)] (future (f (nth parts index))))
Run Code Online (Sandbox Code Playgroud)
没有立即创造所有的期货; 它返回一个惰性序列,在序列内容实现之前不会创建未来.实现延迟序列的代码是:
(vec (flatten (map deref futures)))
Run Code Online (Sandbox Code Playgroud)
在这里,map返回由滞后的未来序列支持的解除引用的未来结果的懒惰序列.由于vec消耗是由生成的序列产生的map,因此每个新的未来在前一个完成之前不会被提交进行处理.
要获得并行处理,您不需要懒惰地创建期货.尝试包装for你在a里面创建未来的循环doall.
您看到代理商有所改进的原因是(apply await agents)在您收集代理商结果之前立即致电.您的start-agents函数也返回一个惰性序列,并不实际调度代理操作.实现细节apply是它完全实现传递给它的小序列(不超过20项).传递的副作用是实现序列,并且在传递agents给apply所有代理动作之前调度它们await.
| 归档时间: |
|
| 查看次数: |
112 次 |
| 最近记录: |