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