Clojure ^:const 是如何工作的? [英] How does Clojure ^:const work?
问题描述
我试图了解 ^:const
在 clojure 中的作用.这就是开发文档所说的.http://dev.clojure.org/display/doc/1.3
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
(定义常量{:圆周率 3.14:e 2.71})
(def constants {:pi 3.14 :e 2.71})
(def ^:const pi (:pi 常量))(def ^:const e (:e 常量))
(def ^:const pi (:pi constants)) (def ^:const e (:e constants))
在映射中查找 :e 和 :pi 的开销发生在编译时,因为 (:pi 常量) 和 (:e 常量) 在评估它们的父 def 形式时被评估.
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.
这令人困惑,因为元数据用于绑定到符号 pi
的 var,以及绑定到符号 e
的 var,但下面的句子说它有助于加快映射查找,而不是 var 查找.
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.
有人可以解释一下 ^:const
正在做什么以及使用它背后的基本原理吗?这与使用巨大的 let
块或使用像 (pi)
和 (e)
这样的宏相比如何?
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)
?
推荐答案
这对我来说似乎是个坏例子,因为关于 map-lookup 的内容只是混淆了问题.
That looks like a bad example to me, since the stuff about map-lookup just confuses the issue.
一个更现实的例子是:
(def pi 3.14)
(defn circ [r] (* 2 pi r))
在这种情况下,圆周的主体被编译成在运行时取消引用 pi 的代码(通过调用 Var.getRawRoot),每次调用圆周.
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 circ2 [r] (* 2 pi r))
在这种情况下,circ2
被编译成完全相同的代码,就像它是这样编写的:
In this case, circ2
is compiled into exactly the same code as if it had been written like this:
(defn circ2 [r] (* 2 3.14 r))
即跳过了对 Var.getRawRoot 的调用,节省了一点时间.这是一个快速测量,其中 circ 是上面的第一个版本,而 circ2 是第二个:
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屋!