Clojure ^:const如何工作? [英] How does Clojure ^:const work?
问题描述
我试图理解clojure中 ^:const
是什么。这是dev docs说的。 http://dev.clojure.org/display/doc/1.3
(def constants
{:pi 3.14
:e 2.71})
^:常数pi(:pi常数))
(def ^:const e(:e constants))
查找的开销:e和: pi在映射中发生在编译时,因为(:pi常数)和(:e常数)在评估其父代def形式时进行评估。
$ b b
这是令人困惑的,因为元数据是var绑定到符号 pi
,var绑定到符号 e
,但下面的句子说它有助于加快地图查找,而不是var查找。
有人可以解释什么 ^:const
是做什么和使用它的理由?这与使用巨大的让
块或使用像(pi)
和(e)
?
这对我来说是一个糟糕的例子, map-lookup只是混淆了问题。
一个更现实的例子是:
(def pi 3.14)
(defn circumference [r](* 2 pi r))
在这种情况下,圆周的主体被编译成代码,在运行时(通过调用Var.getRawRoot)取消引用pi,每次调用圆周。
(def ^:const pi 3.14)
(defn circumference [r](* 2 pi r))
在这种情况下,圆周编译成完全相同的代码,就像它是这样编写的:
(defn circumference [r](* 2 3.14 r))
也就是说,调用Var.getRawRoot被跳过,这节省了一点时间。这里是一个快速测量,其中circ是上面的第一个版本,circ2是第二个版本:
user& (时间(dotimes [_ 1e5](circ 1)))
经过时间:16.864154 msecs
用户> (时间(dotimes [_ 1e5](circ2 1)))
经过时间:6.854782 msecs
I'm trying to understand what ^:const
does in clojure. This is what the dev docs say. http://dev.clojure.org/display/doc/1.3
(def constants {:pi 3.14 :e 2.71})
(def ^:const pi (:pi constants)) (def ^:const e (:e constants))
The overhead of looking up :e and :pi in the map happens at compile time, as (:pi constants) and (:e constants) are evaluated when their parent def forms are evaluated.
This is confusing since the metadata is for the var bound to symbol pi
, and the var bound to symbol e
, yet the sentence below says it helps speed up the map lookups, not the var lookups.
Can someone explain the what ^:const
is doing and the rationale behind using it? How does this compare to using a giant let
block or using a macro like (pi)
and (e)
?
That looks like a bad example to me, since the stuff about map-lookup just confuses the issue.
A more realistic example would be:
(def pi 3.14)
(defn circumference [r] (* 2 pi r))
In this case, the body of circumference is compiled into code that dereferences pi at runtime (by calling Var.getRawRoot), each time circumference is called.
(def ^:const pi 3.14)
(defn circumference [r] (* 2 pi r))
In this case, circumference is compiled into exactly the same code as if it had been written like this:
(defn circumference [r] (* 2 3.14 r))
That is, the call to Var.getRawRoot is skipped, which saves a little bit of time. Here is a quick measurement, where circ is the first version above, and circ2 is the second:
user> (time (dotimes [_ 1e5] (circ 1)))
"Elapsed time: 16.864154 msecs"
user> (time (dotimes [_ 1e5] (circ2 1)))
"Elapsed time: 6.854782 msecs"
这篇关于Clojure ^:const如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!