以下是对行为的表现记录。我不确定是否进行了反射操作,但性能损失(约 1300 倍)表明可能如此。
user=> (use 'criterium.core)
nil
user=> (def b (make-array Double/TYPE 1000 1000))
#'user/b
user=> (quick-bench (aget ^"[[D" b 304 175))
WARNING: Final GC required 3.5198021166354323 % of runtime
WARNING: Final GC required 29.172288684474303 % of runtime
评估计数 : 63558 在 6 样本中的 10593 次调用。
执行时间平均值 : 9.457308 µs
执行时间标准偏差 : 126.220954 纳秒
执行时间下四分位数 : 9.344450 µs ( 2.5%)
执行时间上四分位数 : 9.629202 µs (97.5%)
使用的开销 : 2.477107 纳秒
一种解决方案是使用多个 aget。
user=> (quick-bench (aget ^"[D" (aget ^"[[D" b 304) 175))
WARNING: Final GC required 40.59820310542545 % of runtime
评估计数 : 62135436 在 6 样本中的 10355906 次调用。
执行时间平均值 : 6.999273 ns
执行时间标准偏差 : 0.112703 ns
执行时间下四分位数 : 6.817782 ns ( 2.5%)
执行时间上四分位数 : 7.113845 ns (97.5%)
使用的开销 : 2.477107 纳秒
*原因:内联版本仅适用于 2 个参数,否则会进行反射。