2015-04-03 36 views
1

向量中的clojure是執行操作的高性能方法,因爲內部值是取消裝箱的。我可以創建一個這樣的數組:初始化clojure中的大向量的有效方法

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

但它是非常緩慢的。有更快的方法(必須有)?注意:對於assoc來說,預分配矢量很重要,因爲如果它嘗試將元素設置超出矢量的長度,assoc將生成一個超出邊界的錯誤。

編輯:

這對現在的解決方案(參見答案)。 Leon Grapenthin將其作爲github上的一個bug登錄到here

+0

顯然'矢量一個可變超載-of'沒有針對大輸入進行優化。我在這裏創建了一個關於它的問題http://dev.clojure.org/jira/browse/CLJ-1695 – 2015-04-03 19:55:20

+0

僅供參考它現在已經固定在主頁上https://github.com/clojure/clojure/commit/bcb8e9a7aa0b0588b4872384256d86bf53d12f15 – 2015-04-10 18:03:12

回答

1

運行OP的代碼,以獲得我的機器上的基準時間。 (Mac Pro的2009年2.66 GHz的四核英特爾®至強®,48 GB RAM。Clojure的1.6.0。的Java 1.8.0_40 Java的熱點(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 
+0

I' m驚訝像'n-conj'這樣的東西已經不存在了,但是我找不到它。 – 2015-04-03 15:57:19

+0

注意:我在Clojure 1.7 Alpha 6上運行了計時,而'(進入...版本更快,大約27毫秒,n-conj在30毫秒,所以'n-conj'更快比1.6還慢,但是1.7'進入'慢了'(應用...'仍然很慢,在860毫秒。 – 2015-04-04 06:07:05