2024年Clojure状态调查!中分享你的想法。

欢迎!请参阅关于页面以了解更多关于如何使用本站的信息。

0投票
Clojure
以下是Michał Marczyk在以下讨论线程中发现的一个性能较差的示例的描述。

以下两个编译版本的差异


(defn foo [x]
  (if (> x 0)
    (inc x)
    (locking o
      (dec x))))





(defn bar [x]
  (if (> x 0)
    (inc x)
    (let [res (locking o
                               (dec x))]
      res)))


非常显著。foo被编译到一个类中,调用通过一个调用方法处理;bar被编译成带有bar的一个类和额外的一个类来处理(locking o (dec x))部分 - 可能与手动编写锁定部分的版本非常相似(尽管我还没有真正查看)。内部函数是闭包,所以调用它涉及到一个闭包对象的分配;它的构造函数接收闭包的本地变量作为参数并将它们存储在两个字段中(锁和x)。然后它们在闭包的调用方法主体中等中被加载。


注意:摘要行可能过于狭窄地描述了根本原因,这仅仅是首次注意到并检查这种情况的第一个例子。如果诊断出这个问题,请更正摘要和描述。

在此处查看Clojure群组上的讨论线程:https://groups.google.com/forum/#!topic/clojure/x86VygZYf4Y

2 答案

0投票
_由:hiredman_发表的评论

也许是其他人已经清楚,但这对我来说并不立即清楚

原因


(defn bar [x]
  (if (> x 0)
    (inc x)
    (let [res (locking o
                               (dec x))]
      res)))


生成了一个二类锁解宏,其中包含一个在它的展开中的 try/finally 结构。

将 try/finally 结构的结果绑定到一个结果(如 let 中)将需要一些真正的复杂代码生成,不应添加额外的函数,因此 Clojure 编译器当然会添加额外的函数。
0投票
参考:[https://clojure.atlassian.net/browse/CLJ-1296](https://clojure.atlassian.net/browse/CLJ-1296) (由 jafingerhut 报告)
...