评论者:alexyakushev
我已经尝试实现了(链接:~alexmiller)建议的实现。附带的补丁使用 getComponentType 代替了字符串魔法,并且与第一个补丁相比,引入了以下改进:
- 现在也支持了 aset。除了最后一个索引以外的所有索引都展开到 {{RT.aget}} 调用中,最外层的调用展开到 {{RT.aset}}。
- 如果内联版本在任何点上都无法解析数组的类型,那么,而不是展开成 N 个 {{RT.aget}} 调用(这将导致 N 个编译器反射点),它将生成一个调用非内联的 {{aget}} 调用,该调用将使用 {{Array.get}}(这更快)。
不利的是,到现在为止,对 {{aset}} 的多参数调用会在编译器中触发反射,而以前使用的是 {{Array.set}}。我觉得这些角落是否也需要平滑处理,或者实际上在这种情况下,反射更加明显(在编译器警告中显示)会更好。
我还附上了验证示例的 REPL 日志(使用 clj-java-decompiler)。将它们转换为测试会更好,但我还不知道如何做。
另外,我不得不使用一种技巧 {{((var aget) ...)}} 来强制调用非内联版本。我不太喜欢这样做,但还没有想出更好的方法。另一种方法是将在非内联版本中分离为独立的私有函数,但我不想再向核心命名空间添加更多的变量。