评论者:alexyakushev
我尝试了 (link: ~alexmiller) 提议的实现。附加的补丁使用 getComponentType 而不是字符串魔法,与第一个补丁相比,以下是一些改进:
- 现在也支持 aset。除了最后一个索引之外的所有索引都被展开为 {{RT.aget}} 调用,最外层的调用被展开为 {{RT.aset}}。
- 如果内联版本在任何时候无法解析数组的类型,那么它将生成一个非内联的 aget 调用的调用,该调用将使用 {{Array.get}}(这更快),而不是展开成 N 个 {{RT.aget}} 调用(这将导致 N 个编译器反射点)。
缺点是,现在调用多参数的 aset 将触发编译器的反射,而之前是调用 {{Array.set}}。我怀疑是否应该将这些角落问题也平滑处理,或者在这种情况下更偏好使反射更加明显(显示在编译器警告中)。
我还附加了验证示例的 REPL 日志(使用 clj-java-decompiler)。如果能将其转换为测试将很理想,但我还不知道如何做。
顺便提一下,我不得不使用一个黑客手段 {{((var aget) ...)}} 来强制调用非内联版本。不得不说这个方法不太满意,但我还没有想出更好的办法。另一种方法是将非内联版本分成一个单独的私有函数,但我不想向核心命名空间中加入更多的变量。