如何记录clojure中函数调用的时间
How can I record time for function call in clojure
我是 Clojure 的新手。我正在使用 java 调用 Clojure 函数,我想记录特定行的 clojure 代码执行所花费的时间:
假设我的 clojure 函数是:
(defn sampleFunction [sampleInput]
(fun1 (fun2 sampleInput))
我正在从 java 调用上面的函数,其中 returns 一些字符串值,我想记录执行 fun2 所花费的时间。
我有另一个函数 logTime,它将传递给它的参数写入某个数据库:
(defn logTime [time]
.....
)
我的问题是:如何修改我的 sampleFunction(..) 以调用 logTime 来记录执行 fun2 所花费的时间。
提前致谢。
我不完全确定你的代码的不同部分如何组合在一起并与 Java 互操作,但这里有一些可以按照你描述的方式工作。
要获取一段代码的执行时间,有一个核心函数叫做time
。但是,这个函数不会 return 执行时间,它只是 prints 它...所以假设你想记录将那个时间存入数据库,我们需要编写一个宏来捕获 fun2
的 return 值以及执行所花费的时间:
(defmacro time-execution
[& body]
`(let [s# (new java.io.StringWriter)]
(binding [*out* s#]
(hash-map :return (time ~@body)
:time (.replaceAll (str s#) "[^0-9\.]" "")))))
这个宏的作用是将标准输出绑定到 Java StringWriter
,这样我们就可以用它来存储 time
函数打印的任何内容。为了 return fun2
的结果和执行所花费的时间,我们将这两个值打包在一个散列映射中(也可以是其他集合 - 我们稍后会解构它) .请注意,我们对其执行计时的代码包含在对 time
的调用中,因此我们触发了打印副作用并将其捕获在 s#
中。最后,.replaceAll
只是为了确保我们只提取实际数值(以毫秒为单位),因为 time
打印出 "Elapsed time: 0.014617 msecs"
.
形式的内容
将其合并到您的代码中,我们需要像这样重写 sampleFunction
:
(defn sampleFunction [sampleInput]
(let [{:keys [return time]} (time-execution (fun2 sampleInput))]
(logTime time)
(fun1 return)))
我们简单地解构散列映射以访问 fun2
的 return 值和执行时间,然后我们使用 logTime
记录执行时间,最后我们通过在 fun2
.
的 return 值上调用 fun1
来完成
库 tupelo.prof 如果您想捕获一个或多个函数的执行时间并在多次调用中累积它,那么库 tupelo.prof 为您提供了多种选择。一个例子:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[tupelo.profile :as prof]))
(defn add2 [x y] (+ x y))
(prof/defnp fast [] (reduce add2 0 (range 10000)))
(prof/defnp slow [] (reduce add2 0 (range 10000000)))
(dotest
(prof/timer-stats-reset)
(dotimes [i 10000] (fast))
(dotimes [i 10] (slow))
(prof/print-profile-stats)
)
结果:
--------------------------------------
Clojure 1.10.2-alpha1 Java 14
--------------------------------------
Testing tst.demo.core
---------------------------------------------------------------------------------------------------
Profile Stats:
Samples TOTAL MEAN SIGMA ID
10000 0.955 0.000096 0.000045 :tst.demo.core/fast
10 0.905 0.090500 0.000965 :tst.demo.core/slow
---------------------------------------------------------------------------------------------------
如果您想要单个方法的详细计时,the Criterium library 就是您所需要的。从 quick-bench
函数开始。
我是 Clojure 的新手。我正在使用 java 调用 Clojure 函数,我想记录特定行的 clojure 代码执行所花费的时间:
假设我的 clojure 函数是:
(defn sampleFunction [sampleInput]
(fun1 (fun2 sampleInput))
我正在从 java 调用上面的函数,其中 returns 一些字符串值,我想记录执行 fun2 所花费的时间。
我有另一个函数 logTime,它将传递给它的参数写入某个数据库:
(defn logTime [time]
.....
)
我的问题是:如何修改我的 sampleFunction(..) 以调用 logTime 来记录执行 fun2 所花费的时间。
提前致谢。
我不完全确定你的代码的不同部分如何组合在一起并与 Java 互操作,但这里有一些可以按照你描述的方式工作。
要获取一段代码的执行时间,有一个核心函数叫做time
。但是,这个函数不会 return 执行时间,它只是 prints 它...所以假设你想记录将那个时间存入数据库,我们需要编写一个宏来捕获 fun2
的 return 值以及执行所花费的时间:
(defmacro time-execution
[& body]
`(let [s# (new java.io.StringWriter)]
(binding [*out* s#]
(hash-map :return (time ~@body)
:time (.replaceAll (str s#) "[^0-9\.]" "")))))
这个宏的作用是将标准输出绑定到 Java StringWriter
,这样我们就可以用它来存储 time
函数打印的任何内容。为了 return fun2
的结果和执行所花费的时间,我们将这两个值打包在一个散列映射中(也可以是其他集合 - 我们稍后会解构它) .请注意,我们对其执行计时的代码包含在对 time
的调用中,因此我们触发了打印副作用并将其捕获在 s#
中。最后,.replaceAll
只是为了确保我们只提取实际数值(以毫秒为单位),因为 time
打印出 "Elapsed time: 0.014617 msecs"
.
将其合并到您的代码中,我们需要像这样重写 sampleFunction
:
(defn sampleFunction [sampleInput]
(let [{:keys [return time]} (time-execution (fun2 sampleInput))]
(logTime time)
(fun1 return)))
我们简单地解构散列映射以访问 fun2
的 return 值和执行时间,然后我们使用 logTime
记录执行时间,最后我们通过在 fun2
.
fun1
来完成
库 tupelo.prof 如果您想捕获一个或多个函数的执行时间并在多次调用中累积它,那么库 tupelo.prof 为您提供了多种选择。一个例子:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[tupelo.profile :as prof]))
(defn add2 [x y] (+ x y))
(prof/defnp fast [] (reduce add2 0 (range 10000)))
(prof/defnp slow [] (reduce add2 0 (range 10000000)))
(dotest
(prof/timer-stats-reset)
(dotimes [i 10000] (fast))
(dotimes [i 10] (slow))
(prof/print-profile-stats)
)
结果:
--------------------------------------
Clojure 1.10.2-alpha1 Java 14
--------------------------------------
Testing tst.demo.core
---------------------------------------------------------------------------------------------------
Profile Stats:
Samples TOTAL MEAN SIGMA ID
10000 0.955 0.000096 0.000045 :tst.demo.core/fast
10 0.905 0.090500 0.000965 :tst.demo.core/slow
---------------------------------------------------------------------------------------------------
如果您想要单个方法的详细计时,the Criterium library 就是您所需要的。从 quick-bench
函数开始。