LoginSignup
4
4

More than 5 years have passed since last update.

with-time macro

Last updated at Posted at 2015-02-16

Clojureの関数がどれくらい時間がかかるかを計測する場合にはtimeを使うと手っ取り早い。


user=> (time (reduce + 0 (range 10000)))
"Elapsed time: 1.983 msecs"
49995000

timeは内部的にnanoTimeを使っているので精度も高いが使っていて困ったことがあった。
結果の計測値を標準出力に出して終わってしまうことだ。これは実装を見てみてわかった。


user=> (source time)
(defmacro time
  "Evaluates expr and prints the time it took.  Returns the value of
 expr."
  {:added "1.0"}
  [expr]
  `(let [start# (. System (nanoTime))
         ret# ~expr]
     (prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs"))
     ret#))
nil

この計測値を中で使いたい場合もある。メトリクスとしてとっておいて、何かの最適化とかデータとしてためておく場合など。そういった場合のマクロを書いてみた。


(defmacro with-time
  [expr]
  `(let [start# (. System (nanoTime))
         ret# ~expr
         elapsed# (/ (double (- (. System (nanoTime)) start#)) 1000000.0)]
         [elapsed# ret#]))

基本はtimeの実装をほとんど流用しているけれど、こうすることで返り値の第一引数に計測値が入ってくる。


user=> (with-time (reduce + 0 (range 10000)))
[1.161 49995000]
4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4