【问题标题】:What is the Clojure equivalent of a "public static final" constant in Java什么是 Java 中“公共静态最终”常量的 Clojure 等价物
【发布时间】:2011-03-17 15:11:00
【问题描述】:

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

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

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

【问题讨论】:

    标签: java performance optimization clojure constants


    【解决方案1】:

    我认为def-ing 全局命名空间中的东西已经尽可能接近了。

    【讨论】:

    • 添加 :const 元数据将导致它在编译时被内联,请参阅@amalloy 的回答。全局 def 是 var,虽然关闭,但可以调整并在运行时解决。
    【解决方案2】:

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

    编辑

    显然它是 Clojure 1.3,它是 ^:const,而不是 ^:constant。有关摘要,请参阅 How does Clojure ^:const work?

    【讨论】:

      【解决方案3】:

      没有defconst,所以只使用全局定义是惯用的;就优化而言,JIT 会让事情变得更快。

      【讨论】:

        【解决方案4】:

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

        (defmacro my-constant [] 5)

        这是相当丑陋的,但性能关键的代码总是很丑陋,我猜。

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

        不过,请注意您放入宏的内容!除了一些文字常量外,我不会这样做。尤其不是对象。

        【讨论】:

          【解决方案5】:

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

          【讨论】:

          • 谢谢 - 我是否正确地说,如果你不这样做,那么每次访问常量时都会取消引用 var?
          【解决方案6】:

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

          【讨论】:

          • 如果他想要一些可变的东西,他会要求一个常数,无论如何你通常会用原子制作一个列表。你可以创建一个 atom 列表或 ref 列表。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多