我做了一个简单的性能测试:创建900000大小的数组并阅读它的所有元素。
(time (let [array (byte-array 900000)]
(loop [i (- 900000 1)]
(when (< 0 i)
(aget array i)
(recur (- i 1))))))
"Elapsed time: 10.244612 msecs"
然后我想确定要动态创建的数组类型,为简单起见,这里定义了重言式hashmap:
(def types {:byte-array byte-array :int-array int-array})
现在我再次进行测试并获得了很大的性能差距:
(time (let [array ((types :byte-array) 900000)]
(loop [i (- 900000 1)]
(when (< 0 i)
(aget array i)
(recur (- i 1))))))
"Elapsed time: 7190.233155 msecs"
解决方法:
(time (let [^bytes array ((types :byte-array) 900000)]
(loop [i (- 900000 1)]
(when (< 0 i)
(aget array i)
(recur (- i 1))))))
"Elapsed time: 12.48304 msecs"
问题是如何动态输入提示clojure?有谁知道引擎盖下会发生什么?
答案 0 :(得分:1)
Clojure是一种编译语言。您的测试代码将始终首先编译,然后执行。因此很明显,代码不能同时专门用于两种不同的类型。
如果要支持不同类型的原始数组的特化,您唯一的机会是使用宏并使用编译时常量来决定每次宏调用需要哪种特化。您可以围绕它构建便利,例如根据检测到的数组运行时类型调度到适当编译的函数。