为了试图理解core.async,我成功地实现了"Skynet 100万微基准“,即:
创造一个演员(哥鲁丁,无论如何),产生10个新演员,每个演员产生10个以上的演员,等等,直到100万演员在最后一级被创造出来。然后,它们返回其序号(从0到999999),该序号在上一级别上求和,并返回上游,直到到达根参与者。(答案应该是499999500000)。
这里有多种语言的实现:
https://github.com/atemerev/skynet
以下是我彻底失败的尝试:
(defn skynet [chan num size div]
(if (= 1 size)
(>! chan num)
(>! chan (reduce + (let [rc (async/chan)
n (/ size div)]
(doall (for [i [0 div]]
(skynet rc (+ num (* i n)) n div))
(for [i [0 div]] (<! rc))))))))我试着在REPL的一个围棋区里把它叫做:
(time (go (<!! (skynet (async/chan) 0 1000000 10))))我可能对有关core.async的许多事情(以及懒惰的评估)感到非常困惑。
我应该如何解决这个问题,为什么?
发布于 2016-02-16 00:13:23
有关于一些限制能够做什么的core.async,所以您不能使用map或for函数。
您的实现非常接近正确的实现。以下几点:
go == one进程,所以您只是创建一个进程,而不是1m进程。<!!将在go块外使用<!将在go块内部使用doall只接受一个参数一个可以改进的工作实现:
(defn skynet [parent num size div]
(go ;; We create a new process each time skynet is called
(if (= 1 size)
(>! parent num)
(let [self (chan)
new-size (/ size div)]
(dotimes [i div] ;; dotimes is more explicit for side effects
(skynet self (+ num (* i new-size)) new-size div))
(loop [i div ;; Manual reduce
t 0]
(if (zero? i)
(>! parent t)
(recur (dec i)
(+ t (<! self)))))))))并称之为:
(time
(do
(def result (chan))
(def x (skynet result 0 1000000 10))
(<!! result)))https://stackoverflow.com/questions/35400990
复制相似问题