Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 如何使用core.async实现Skynet 1m微基准?_Clojure_Channel_Coroutine_Core.async - Fatal编程技术网

Clojure 如何使用core.async实现Skynet 1m微基准?

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

为了尝试理解core.async,我尝试实现了“Skynet 100万微基准”,但没有成功,即:

创建一个演员(goroutine,随便什么),产生10个新演员, 每一个都会产生10个以上的演员,以此类推,直到100万名演员诞生 在最终关卡上创建。然后,他们每个人都返回自己的 序号(从0到999999),在上一个 级别并发送回上游,直到到达根参与者。(修订) 答案应该是49999500000)

这里有多种语言的实现:

这是我完全失败的尝试:

(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,但找不到方法。我对这样一个版本很感兴趣。无论如何,谢谢!