Clojure与“a”的等价物是什么;公开静态决赛“;Java中的常量

Clojure与“a”的等价物是什么;公开静态决赛“;Java中的常量,java,performance,optimization,clojure,constants,Java,Performance,Optimization,Clojure,Constants,我正在编写一些Clojure代码,它依赖于许多常量 它们将在紧密的内部循环中使用,因此Clojure编译器+JVM组合将尽可能有效地使用和优化它们,这一点很重要。出于同样的目的,我通常会在Java中使用“publicstaticfinal”常量 声明这些的最佳方式是什么?我认为def-ing全局名称空间中的东西是尽可能接近的。如上所述使用def或atom,记住,数据是不可变的,所以如果在列表中声明一些常量,它们不会改变。没有defconst,因此,仅仅使用全局def是惯用的;就优化而言,JIT将

我正在编写一些Clojure代码,它依赖于许多常量

它们将在紧密的内部循环中使用,因此Clojure编译器+JVM组合将尽可能有效地使用和优化它们,这一点很重要。出于同样的目的,我通常会在Java中使用“publicstaticfinal”常量


声明这些的最佳方式是什么?

我认为
def
-ing全局名称空间中的东西是尽可能接近的。

如上所述使用def或atom,记住,数据是不可变的,所以如果在列表中声明一些常量,它们不会改变。

没有
defconst
,因此,仅仅使用全局def是惯用的;就优化而言,JIT将使事情变得更快。

如果真的、真的、真的希望常量到位(我相信,JIT会注意到值是常量,并做正确的事情),您可以使用宏

(defmacro my-constant [] 5)
这相当难看,但我想性能关键型代码总是难看的

(do-stuff (my-constant) in-place)

不过,请注意你在宏中输入的内容!除了一些文字常量之外,我不会这么做。特别是非对象。

如果仅仅使用
def
不够快,您可以尝试在进入紧循环之前创建
let
绑定别名,以避免每次都通过var。

我相信Clojure 1.3(或者可能是1.4)允许您在
def
上放置
^:constant
标记,向编译器表明这应该是一个常量,所有引用都应该在编译时解析

编辑
显然它是Clojure 1.3,它是
^:const
,而不是
^:constant
。请参阅以获取摘要。

如果他想要可变的东西,他会要求一个常数,无论如何,你通常会用原子列一个列表。您可以创建一个atom列表或ref列表。谢谢-如果您不这样做,那么每次访问常量时,它都会取消对var的引用。添加:const元数据将导致它在编译时内联,请参阅@amalloy提供的答案。全局def是vars,在关闭时可以对其进行调整并在运行时得到解析。