请在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))部分——可能非常类似于手动编码锁部分的输出(尽管我还没有真正查看过)。内部函数是一个闭包,所以调用它涉及分配一个闭包对象;其构造器接收闭包变量作为参数并将它们存储在两个字段(lockee和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(由jafingerhut报告)
...