为什么时间需要是一个宏?
Why does time need to be a macro?
Clojure source code给出了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#))
为什么这需要是一个宏?一个函数做不到怎么办?
因为函数在开始使用它们之前会对其参数求值。您可以将 time
写成函数并尝试调用它:
(defn my-time [expr]
(let [start (System/nanoTime)
ret expr]
(prn (str "Elapsed time: " (/ (double (- (System/nanoTime) start)) 1000000.0) " msecs"))
ret))
(my-time (Thread/sleep 1000))
"Elapsed time: 0.005199 msecs"
=> nil
与 time
宏比较:
(time (Thread/sleep 1000))
"Elapsed time: 1000.1222 msecs"
=> nil
函数 my-time
评估了参数 (Thread/sleep 1000)
,符号 expr
获得了值 nil
,然后该函数的主体发生了 - 之后不久调用了两个 (System/nanoTime)
彼此,因为已经计算了 expr
的值。
宏 time
未计算 (Thread/sleep 1000)
,但扩展为:
(macroexpand `(time (Thread/sleep 1000)))
=>
(let*
[start__6136__auto__ (. java.lang.System (clojure.core/nanoTime)) ret__6137__auto__ (java.lang.Thread/sleep 1000)]
(clojure.core/prn
(clojure.core/str
"Elapsed time: "
(clojure.core//
(clojure.core/double (clojure.core/- (. java.lang.System (clojure.core/nanoTime)) start__6136__auto__))
1000000.0)
" msecs"))
ret__6137__auto__)
函数的调用顺序为:(System/nanoTime)
、(Thread/sleep 1000)
和其他 (System/nanoTime)
,returns 正确时间。
Clojure source code给出了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#))
为什么这需要是一个宏?一个函数做不到怎么办?
因为函数在开始使用它们之前会对其参数求值。您可以将 time
写成函数并尝试调用它:
(defn my-time [expr]
(let [start (System/nanoTime)
ret expr]
(prn (str "Elapsed time: " (/ (double (- (System/nanoTime) start)) 1000000.0) " msecs"))
ret))
(my-time (Thread/sleep 1000))
"Elapsed time: 0.005199 msecs"
=> nil
与 time
宏比较:
(time (Thread/sleep 1000))
"Elapsed time: 1000.1222 msecs"
=> nil
函数 my-time
评估了参数 (Thread/sleep 1000)
,符号 expr
获得了值 nil
,然后该函数的主体发生了 - 之后不久调用了两个 (System/nanoTime)
彼此,因为已经计算了 expr
的值。
宏 time
未计算 (Thread/sleep 1000)
,但扩展为:
(macroexpand `(time (Thread/sleep 1000)))
=>
(let*
[start__6136__auto__ (. java.lang.System (clojure.core/nanoTime)) ret__6137__auto__ (java.lang.Thread/sleep 1000)]
(clojure.core/prn
(clojure.core/str
"Elapsed time: "
(clojure.core//
(clojure.core/double (clojure.core/- (. java.lang.System (clojure.core/nanoTime)) start__6136__auto__))
1000000.0)
" msecs"))
ret__6137__auto__)
函数的调用顺序为:(System/nanoTime)
、(Thread/sleep 1000)
和其他 (System/nanoTime)
,returns 正确时间。