您好,Clojure专家,
我正在尝试在Clojure 1.3中做一些计时测试,我想我应该问一个基于现有代码的问题,这些代码解决了一个改编自 this blog post的微分方程。
代码如下:
;; the differential equation is
;; dy/dt = f(y,t) = t - y
(defn f [t y] (- t y))
;; solve using Euler's method
(defn solveEuler [t0 y0 h iter]
(if (> iter 0)
(let [t1 (+ t0 h)
y1 (+ y0 (* h (f t0 y0)))]
(recur t1 y1 h (dec iter)))
[t0 y0 h iter]))
(defn multipleSolveEuler []
(let [steps '(1 10 100 1000 10000 100000)
results (map #(second (solveEuler 0.0 0.0 (/ 1.0 %) %)) steps)
errors (map #(- (Math/exp -1) %) results)]
(partition 3 (interleave steps results errors))))
(def *cpuspeed* 2.0)
(defmacro cyclesperit [expr its]
`(let [start# (. System (nanoTime))
ret# ( ~@expr (/ 1.0 ~its) ~its )
finish# (. System (nanoTime))]
(int (/ (* *cpuspeed* (- finish# start#)) ~its))))
(defn solveEuler-2 [t0 y0 h its]
(let [zero (int 0)]
(loop [t0 (double t0), y0 (double y0), h (double h), its (int its)]
(if (> its zero)
(let [t1 (+ t0 h)
y1 (+ y0 (* h (- t0 y0)))]
(recur t1 y1 h (dec its)))
[t0 y0 h its]))))所以当我说
(time solveItEuler-2 0.0 1.0 (/ 1.0 1000000000) 1000000000))我在一个6个月大的Macbook pro上得到了6004.184毫秒的时间。我再次发出该命令,并且我在相同的时间内运行。但是当我运行它另外3次时,我得到的时间范围是3500毫秒。我以前在其他代码片段中注意到了这一点,并想知道为什么会这样。我想我希望在连续的运行中有大致相似的执行时间。
是我对“时间”是如何工作的缺乏理解,是我遗漏了什么,还是在幕后发生了某种缓存?
谢谢。
发布于 2012-03-10 04:19:03
相关的不是time,而是在运行时优化代码的JVM。您观察到的情况是典型的;执行时间将下降,然后在大约3次调用后稳定下来。
发布于 2012-03-11 12:59:59
我推荐使用Criterium库进行基准测试。它旨在处理在JVM上运行的基准测试代码的陷阱。
发布于 2012-03-12 18:27:15
(这是对Viebel请求更多信息的回应,这对于一条评论来说变得太多字符,这不是对orig的回答。q)。
有相当多的自由度: JVM和堆设置,启动时间,预热运行次数,使用的数据结构,内联方法的大小。
http://www.infoq.com/articles/java-threading-optimizations-p2
http://groups.google.com/group/clojure/browse_thread/thread/776943086de213f9#
http://stas-blogspot.blogspot.com/2011/07/most-complete-list-of-xx-options-for.html
http://www.azulsystems.com/blog/cliff/2009-09-06-java-vs-c-performanceagain
https://stackoverflow.com/questions/9640310
复制相似问题