Clojure码的时序分析

Clojure码的时序分析,clojure,Clojure,大家好,Clojure专家 我试图在Clojure 1.3中做一些计时测试,我想我会问一个问题,这个问题基于一段现有的代码,该代码解决了一个根据该代码改编的微分方程 代码如下: ;; the differential equation is ;; dy/dt = f(y,t) = t - y

大家好,Clojure专家

我试图在Clojure 1.3中做一些计时测试,我想我会问一个问题,这个问题基于一段现有的代码,该代码解决了一个根据该代码改编的微分方程

代码如下:

;; 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毫秒的范围内。我以前在其他代码片段中也注意到了这一点,我想知道为什么会这样。我想我会期望在连续运行中的执行时间大致相同

是因为我不了解“时间”是如何工作的,是因为我错过了什么,还是因为某种缓存在引擎盖下发生了


谢谢。

相关的不是时间,而是JVM在运行时优化代码。你所观察到的是典型的;执行时间将下降,然后在大约3次调用后稳定下来。

我建议使用库进行基准测试。它旨在处理在JVM上运行的基准测试代码的缺陷。

(这是对Viebel请求更多信息的响应,该请求对于单个注释来说太多了,这不是对orig.Q的回答)

有很多自由度:JVMGC和堆设置、启动时间、预热运行次数、使用的数据结构、内联方法的大小



我明白了。因此,为了做一个相当准确的计时分析,在说“这段代码需要X秒才能运行”之前,是否需要多次运行一段代码。这适用于JVM上运行的所有语言。继续运行它,直到得到稳定的值。您能提供一些关于JVM这种行为的资料吗?@Yehonathan。你想搜索“JVM预热”、“热点内联”、-XX:MaxInlineSize“我认为你应该简化你的问题,并提供一个简单得多的代码段。虽然我的问题不是关于某个特定的代码段,而是关于在JVM上进行计时分析的结果,但上面的例子有一个“足够大”的问题“我希望看到巨大的差异——这就是我选择它的原因。