2010-06-14 63 views
40

我知道我可以花時間評估一個函數可以使用時間函數/宏在屏幕上/標準輸出打印出來。如何在Clojure中對函數進行基準測試?

時間宏返回評估函數的值,這使得它內聯使用它的好處。不過,我想在特定情況下自動測量運行時間。

是否有一個函數可以返回某個庫中的已用時間以幫助進行基準測試?

+0

可能的重複[分析工具爲Clojure?](http://stackoverflow.com/questions/2974916/profiling-tool-for-clojure) – 2015-04-04 02:56:59

+0

我不這麼認爲,提到的問題是關於外部基準測試,這個問題更多的是關於如何使用代碼。我必須承認有人在5年前的問題中尋找重複的東西感到驚訝。 – 2015-04-13 12:26:34

回答

27

您可能想看看Hugo Duncan的Clojure基準圖書館 - Criterium

自述:

繞圈措施表達式的計算時間。它旨在解決基準測試的一些缺陷,尤其是針對JVM的基準測試。

這包括:

  • 多種評估的統計處理
  • 列入一個預熱時間,設計爲允許JIT編譯器測試之前優化它的代碼
  • 吹掃GC的,以分離測試前來自GC狀態的時間
  • 測試後最終強制GC以估計清除對時間結果的影響
30

如果只想以編程方式捕獲字符串,可以在使用時間之前將* out *綁定到其他東西。

user=> (def x (with-out-str (time (+ 2 2)))) 
#'user/x 
user=> x 
"\"Elapsed time: 0.119 msecs\"\n" 

如果你想在格式更多的控制,那麼你可以創建自己的時間版本使用Java的系統時間的方法,這是引擎蓋下的時間宏觀用途反正:

user => (macroexpand '(time (+ 2 2))) 
(let* [start__4197__auto__ (. java.lang.System (clojure.core/nanoTime)) 
     ret__4198__auto__ (+ 2 2)] 
    (clojure.core/prn (clojure.core/str "Elapsed time: " (clojure.core//  
      (clojure.core/double 
       (clojure.core/- (. java.lang.System (clojure.core/nanoTime)) 
           start__4197__auto__)) 1000000.0) " msecs")) 
ret__4198__auto__) 

採取這種基本結構,並用您喜歡的任何報告機制取代呼叫prn

+4

+1使用macroexpand在引擎蓋下進行挖掘! – mikera 2010-06-15 00:57:14

+1

謝謝,我也是從這個開始看這個。標準庫真的適合這項法案。但除非你知道Haskell庫,否則你不會偶然使用谷歌偶然發現它。 – 2010-06-15 05:58:27

+1

@PeterTillemans嗯,我們現在是,因爲它在StackOverflow中提到。 :-) – 2013-12-05 18:57:44

相關問題