有效的方法来初始化clojure中的大向量

时间:2015-04-03 14:07:02

标签: performance clojure

clojure中的Vector-of是一种执行操作的高效方法,因为内部值是未装箱的。我可以像这样创建一个数组:

(time (count (apply vector-of :double (repeat 100000 0))));
; "Elapsed time: 1703.597 msecs"

但它很慢。有更快的方法(必须有)吗?注意:向量的预分配对于assoc非常重要,因为如果它试图将元素设置为超出向量的长度,则assoc将生成越界错误。

修改

现在有一个解决方案(见答案)。 Leon Grapenthin在github上发布了这个bug here

1 个答案:

答案 0 :(得分:1)

运行OP的代码,以便在我的机器上获得基准时间。 (Mac Pro 2009 2.66 GHz四核Intel Xeon,48 GB RAM.Clojure 1.6.0 .Java 1.8.0_40 Java HotSpot(TM)64位服务器VM。)

user> (time (count (apply vector-of :double (repeat 100000 0))))
"Elapsed time: 992.688709 msecs"
100000

尝试(repeat 100000 0.0)以消除长到双转换。没什么变化。

user> (time (count (apply vector-of :double (repeat 100000 0.0))))
"Elapsed time: 965.876047 msecs"
100000

创建矢量,然后更快地添加元素:

user> (time (count (into (vector-of :double) (repeat 100000 0.0))))
"Elapsed time: 52.856371 msecs"
100000

快一点,不要建立一个懒惰的序列:

(defn n-conj [n coll elem]
  (if (zero? n)
    coll
    (recur (dec n) (conj coll elem) elem)))

(time (count (n-conj 100000 (vector-of :double) 0.0)))
"Elapsed time: 37.86183 msecs"
100000
相关问题