web-dev-qa-db-ja.com

Clojureの関数をベンチマークする方法は?

関数を評価するのにかかる時間を取得できることはわかっています。時間関数/マクロを使用して、画面/標準出力に出力できます。

時間マクロは、評価された関数の値を返すため、インラインで使用するのに最適です。ただし、特定の状況下でランタイムを自動的に測定したいと思います。

このベンチマークに役立つライブラリの経過時間を返す関数はありますか?

41
Peter Tillemans

ヒューゴ・ダンカンのClojureのベンチマークライブラリを調べてみてください-- クリテリウム

READMEから:

クリテリウムは、式の計算時間を測定します。これは、ベンチマーク、特にJVMでのベンチマークの落とし穴のいくつかに対処するように設計されています。

これも:

  • 複数の評価の統計処理
  • jITコンパイラがコードを最適化できるように設計されたウォームアップ期間が含まれています
  • テスト前のGC状態からタイミングを分離するための、テスト前のgcのパージ
  • タイミング結果に対するクリーンアップの影響を推定するためのテスト後の最終的な強制GC
27
Michał Marczyk

プログラムで文字列をキャプチャしたいだけの場合は、timeを使用する前に* out *を他の何かにバインドできます。

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

フォーマットをより細かく制御したい場合は、Javaのシステム時刻メソッドを使用して独自のバージョンのtimeを作成できます。これは、とにかくtimeマクロが内部で使用するものです。

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の呼び出しを任意のレポートメカニズムに置き換えます。

31
G__

関数のJavaバインディングを生成する場合(およびClojure Mavenプラグインの再構成を使用する場合)、JMHを使用することもできます( http://openjdk.Java.net/projects/ code-tools/jmh / )これはおそらく最高のJVMマイクロベンチマークハーネスです。 https://github.com/circlespainter/pulsar-auto-instrument-bench をご覧ください。

0
circlespainter