Временной анализ кода Clojure - PullRequest
3 голосов
/ 10 марта 2012

Привет эксперты 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))

Я получаю время 6004,184 мсек на 6-месячном MacBook Pro. Я снова даю команду, и я в это же время обхожусь. Но когда я запускаю его 3 раза, я получаю время в диапазоне 3500 мсек. Я заметил это раньше для других фрагментов кода, и мне было интересно, почему это так. Полагаю, я ожидал бы примерно одинаковое время выполнения при последовательных запусках.

Это мое непонимание того, как работает "время", что-то, чего мне не хватает, или какое-то кеширование происходит под капотом?

Спасибо.

Ответы [ 3 ]

7 голосов
/ 11 марта 2012

Я рекомендую использовать библиотеку Criterium для тестирования производительности. Он предназначен для устранения ловушек кода для сравнительного анализа, который выполняется на JVM.

7 голосов
/ 10 марта 2012

Это не time, а скорее JVM, оптимизирующая код во время выполнения. То, что вы наблюдаете, типично; время выполнения уменьшится, а затем стабилизируется примерно через 3 вызова.

2 голосов
/ 12 марта 2012

(Это ответ на запрос Viebel для получения дополнительной информации, который стал слишком большим количеством символов для одного комментария. Это не ответ на orig. Q).

Существует довольно много степеней свободы: настройки GV и кучи 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 / наиболее полный список-, из-хх-опции-for.html

http://www.azulsystems.com/blog/cliff/2009-09-06-java-vs-c-performanceagain

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...