我正在编写一些依赖于许多常量的Clojure代码。
它们将在紧密的内部循环中使用,因此通过Clojure编译器+ JVM组合尽可能高效地使用和优化它们非常重要。我通常会在Java中使用“public static final”常量来达到同样的目的。
申报这些内容的最佳方式是什么?
答案 0 :(得分:6)
我认为def
- 全局命名空间中的东西尽可能接近。
答案 1 :(得分:6)
我相信Clojure 1.3(或者可能是1.4)允许你在^:constant
上放置一个def
标签,向编译器表明这应该是一个常量,所有引用都应该在编译时解决 - 时间。
显然它是Clojure 1.3,它是^:const
,而不是^:constant
。有关摘要,请参阅How does Clojure ^:const work?。
答案 2 :(得分:3)
没有defconst
,所以只使用全局def是惯用的;就优化而言,JIT会使事情变得更快。
答案 3 :(得分:3)
如果真的,真的,真的想要常量(我相信,JIT会注意到值是不变的并做正确的事情),你可以使用宏。
(defmacro my-constant [] 5)
这是相当丑陋的,但我认为性能关键代码总是很难看。
(do-stuff (my-constant) in-place)
请注意你放入宏中的内容!我不会超过一些文字常量。特别是不是对象。
答案 4 :(得分:3)
如果仅使用def
的速度不够快,您可以尝试在进入紧密循环之前创建let
绑定别名,以避免每次都通过var。
答案 5 :(得分:2)
如上所述使用def或atom,记住,数据是不可变的,所以如果你在列表中声明一些常量,它们就不会改变。