在Clojure中,为什么rand-int的使用如此复杂?

时间:2015-11-02 02:39:45

标签: random clojure

为什么在它们似乎返回等效结果时使用(reduce + (conj [] (repeat 1 (rand-int 100000))))而不是简单(list (rand-int 100000)),即一个伪随机选择的整数列表?

随机int函数的较长版本来自Carin Meier的书Living Clojure,在她关于core.async的章节中,将用于模拟服务器响应的时间。

  

...我们将模拟调用它们[两个不同的服务器]并让它花费一段随机时间。这个随机的时间量将是一个名为random-add的函数。它使用rand-int函数来选择0到100,000之间的随机整数。 然后它在一个函数中使用它来总结一个填充了随机长度的数字1的向量:

(defn random-add []
    (reduce + (conj [] (repeat 1 (rand-int 100000)))))
     

[强调添加]

我是初学者,再次真的看不出有什么好处,例如:

(defn random-add-lite [] 
    (list (rand-int 100000)))

在我的复制中,据我所知,结果是等效的。有什么区别以及它有何帮助?

谢谢!

修改

以下是本书core.clj示例中的整个core.async文件,以便有兴趣的人可以查看rand-int函数的使用方式。我仍然不明白,但想象一下像Carin Meier一样有能力的开发人员一定有理由......

  (ns async-tea-party.core
(:gen-class)
(:require [clojure.core.async :as async]))

(def google-tea-service-chan (async/chan 10))
(def yahoo-tea-service-chan (async/chan 10))
(def result-chan (async/chan 10))

(defn random-add []
  (reduce + (conj [] (repeat 1 (rand-int 100000)))))

(defn request-google-tea-service []
  (async/go
    (random-add)
    (async/>! google-tea-service-chan
              "tea complimemts of google")))

(defn request-yahoo-tea-service []
  (async/go
    (random-add)
    (async/>! yahoo-tea-service-chan
              "tea complimemts of yahoo")))

(defn request-tea []
  (request-google-tea-service)
  (request-yahoo-tea-service)
  (async/go (let [[v] (async/alts!
                       [google-tea-service-chan
                       yahoo-tea-service-chan])]
              (async/>! result-chan v))))

(defn -main [& args]
  ;; TODO - it seems wasteful to only request one cup
  ;; of tea - so do at least 1000
  (println "Requesting tea")
  (request-tea)
  (println (async/<!! result-chan)))

1 个答案:

答案 0 :(得分:1)

关键在于书中的这句话(强调我的):

  

...我们将模拟调用它们[两个不同的服务器]和让它花费一段随机时间

你建议的(list (rand-int 100000))函数确实会产生类似的结果,效率会更高。你的直觉是对的。但本书中的功能是 故意 效率低下,以便模拟连接到远程服务器,这将花费不明时间返回结果。所以在这个 one 的情况下,低效的函数对于本书的作者试图做的更好。你的函数会以恒定的,可预测的时间返回 - 这会(在这种情况下)会破坏目的。

UPDATE :我刚刚检查过,并且@noisesmith是正确的,repeat的参数被交换了。作者试图创建一个只包含1的随机长度列表,但她实际上创建了一个包含随机整数的长度为1的列表。她应该写(repeat (rand-int 100000) 1)