Clojure 如何使用core.async实现Skynet 1m微基准?
为了尝试理解core.async,我尝试实现了“Skynet 100万微基准”,但没有成功,即: 创建一个演员(goroutine,随便什么),产生10个新演员, 每一个都会产生10个以上的演员,以此类推,直到100万名演员诞生 在最终关卡上创建。然后,他们每个人都返回自己的 序号(从0到999999),在上一个 级别并发送回上游,直到到达根参与者。(修订) 答案应该是49999500000) 这里有多种语言的实现: 这是我完全失败的尝试:Clojure 如何使用core.async实现Skynet 1m微基准?,clojure,channel,coroutine,core.async,Clojure,Channel,Coroutine,Core.async,为了尝试理解core.async,我尝试实现了“Skynet 100万微基准”,但没有成功,即: 创建一个演员(goroutine,随便什么),产生10个新演员, 每一个都会产生10个以上的演员,以此类推,直到100万名演员诞生 在最终关卡上创建。然后,他们每个人都返回自己的 序号(从0到999999),在上一个 级别并发送回上游,直到到达根参与者。(修订) 答案应该是49999500000) 这里有多种语言的实现: 这是我完全失败的尝试: (defn skynet [chan num siz
(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))))))))
(defn天网[chan num size div]
(如果(=1号)
(>!chan num)
(>!chan(reduce+)(let[rc(async/chan)
n(/尺寸div)]
(doall(用于[i[0 div]]
(天网rc(+num(*i n))n分区)
(对于[i[0 div]](
我试着在REPL的围棋区内把这一切都说出来:
(time (go (<!! (skynet (async/chan) 0 1000000 10))))
(时间(go(
我可能对很多关于core.async(以及惰性评估)的事情感到非常困惑
我应该如何着手解决这个问题以及原因?关于core.async能够做什么,有很多限制,因此您不能对
函数使用map
或
您的实现非常接近正确的实现。以下几点:
go
==一个进程,所以您只创建了一个进程,而不是1m
将在围棋区外使用
将在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)))))))))
(定义天网[父数值大小div]
(go;;每次调用skynet时,我们都会创建一个新进程
(如果(=1号)
(>!父数值)
(让[自我(陈)
新尺寸(/size div)]
(dotimes[i div];;dotimes对于副作用更为明确
(天网自身(+num(*i新尺寸))新尺寸div)
(循环[i div;;手动减少
t[0]
(如果(零?i)
(>!父t)
(再次出现(12月1日)
(+t)(
并称之为:
(time
(do
(def result (chan))
(def x (skynet result 0 1000000 10))
(<!! result)))
(时间)
(做
(def结果(chan))
(def x(天网结果0 1000000 10))
(非常感谢!有很多Clojure需要研究,但这肯定会对我有很大帮助,不仅是你的版本,还有你对我代码中错误的评论。奇怪的是,在你的最后一行代码中出现了一些“a/”,我编辑了它:)当然比仅仅使用减速机要慢,但这就是基准测试的重点。我尝试编写一个版本的skynet
函数,该函数将返回一个包含结果的通道(而不是将一个作为参数),并使用async/reduce代替手动reduce,但找不到方法。我对这样一个版本很感兴趣。无论如何,谢谢!