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