除非您在代码中指定,否则 Clojure 不会存储结果,或者通过使用memoize
注释中提到的方法,或者像您一样将计算/结果保存在本地绑定中。
关于一个函数相对于另一个函数有多快的问题,这里有一些代码返回每个函数的执行时间(我不得不模拟这个select-with-probability
函数)。doall
s 是强制评估 的结果所必需的map
。
(defn select-with-probability [x p]
(when (< p 0.5)
x))
(defn rank-selection [population fitness]
(map
#(select-with-probability (sort-by fitness population) %)
(repeatedly (count population) rand)))
(defn rank-selection-let [population fitness]
(let [sorted-population (sort-by fitness population)]
(map
#(select-with-probability sorted-population %)
(repeatedly (count population) rand))))
(let [population (take 1000 (repeatedly #(rand-int 10)))]
(time (doall (rank-selection population <)))
(time (doall (rank-selection-let population <)))
;; So that we don't get the result seq
nil)
这将在我的本地环境中返回以下内容:
"Elapsed time: 95.700138 msecs"
"Elapsed time: 1.477563 msecs"
nil
编辑
为了避免使用let
表单,您还可以使用partial
它接收一个函数和任意数量的参数,并使用提供的参数值返回该函数的部分应用程序。生成的代码的性能与带有表单的代码的顺序相同,let
但更简洁易读。
(defn rank-selection-partial [population fitness]
(map
(partial select-with-probability (sort-by fitness population))
(repeatedly (count population) rand)))
(let [population (take 1000 (repeatedly #(rand-int 10)))]
(time (doall (rank-selection-partial population <)))
;; So that we don't get the result seq
nil)
;= "Elapsed time: 0.964413 msecs"