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

欢迎!请查阅 关于 页面以了解有关此信息的一些更多信息。

+7
编译器
重新标记
;; contrived one but the min repro that I could find
(defn foo [a]
  [(case a
     :f64 0
     :f32 1)
   (case a
     :f64 2
     :f32 3)
   (case a
     :f64 4
     :f32 5)])

这无法编译,出现 '方法大小过大!' 错误。

看起来我们遇到了两个关键词的哈希非常不幸。据我所知,case 宏检查哈希之间的差异 - 如果差异小于8192,则输出一个包含所有中间值的 tableswitch(O(1)),如果差异大于8192,则输出一个 lookupswitch(O(log n))。

例如,在这个例子中,哈希分别是1020273352和1020279615,因此它为两个数字之间的每个数字生成一个 tableswitch 条目(以允许常数时间查找)

在这种情况下,差异约为6200,因此它变成了一个(大型)tableswitch,在同一个函数中有三个这样的东西导致超过64kB的字节码限制。

我成功使用的一个 workaround 是将 case 语句放在立即调用的函数中 - ((fn [] (case ...)))

祝好,

James

1 个答案

0

已选中
恭喜 Alex!
...