我试图理解 ^:const
在 clojure 中的作用。这是开发文档所说的。 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.
这很令人困惑,因为元数据是针对绑定(bind)到符号 pi
的 var,以及绑定(bind)到符号 e
的 var,但下面的句子说它有助于加快速度映射查找,而不是 var 查找。
有人可以解释一下 ^:const
正在做什么以及使用它背后的基本原理吗?这与使用巨大的 let
block 或使用 (pi)
和 (e)
等宏相比如何?
最佳答案
对我来说,这看起来是一个坏例子,因为有关 map 查找的内容只会混淆问题。
一个更现实的例子是:
(def pi 3.14)
(defn circ [r] (* 2 pi r))
在这种情况下,圆周的主体被编译成在运行时取消引用 pi 的代码(通过调用 Var.getRawRoot),每次调用圆周时。
(def ^:const pi 3.14)
(defn circ2 [r] (* 2 pi r))
在这种情况下,circ2
被编译成完全相同的代码,就好像它是这样编写的:
(defn circ2 [r] (* 2 3.14 r))
也就是说,跳过了对 Var.getRawRoot 的调用,这样就节省了一点时间。这是一个快速测量,其中 circ 是上面的第一个版本,circ2 是第二个版本:
user> (time (dotimes [_ 1e5] (circ 1)))
"Elapsed time: 16.864154 msecs"
user> (time (dotimes [_ 1e5] (circ2 1)))
"Elapsed time: 6.854782 msecs"
关于clojure - Clojure 如何 ^ :const work?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9162558/