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));如果大于,则发出一个lookupswitch(O(log n))。

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

在这个例子中,差异大约是6200,这将导致一个(较大的)tableswitch,同一个函数中的三个这样的操作将使其超过64kB的字节码限制。

对我有效的解决方案是将`case`语句放在立即调用的函数中 - `((fn [] (case ...)))

感谢,

James

1 答案

0
by
选定 by
by
给Alex点赞!
...