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

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

问题描述

我试图理解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屋!

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