Clojure ^:const 是如何工作的? [英] How does Clojure ^:const work?

查看:21
本文介绍了Clojure ^:const 是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解 ^: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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆