2015-04-03 5 views
1

Vector-of in clojure - это способ выполнения операций, поскольку внутренние значения распаковываются. Я могу создать такой массив:эффективный способ инициализации большого вектора в clojure

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

Но это очень медленно. Есть ли более быстрый способ (должен быть)? Примечание: преассоляция вектора важна для связывания, так как ассоциатор будет генерировать ошибку вне пределов, если он пытается установить элемент за пределы длины вектора.

Edit:

Это имеет решение сейчас (см ответ). Леон Грапентин опубликовал это как ошибку на github here.

+0

Видимо VARIADIC перегрузка 'вектора -of' не оптимизирован для большого ввода. Я создал проблему об этом здесь http://dev.clojure.org/jira/browse/CLJ-1695 –

+0

FYI теперь исправлено на главном https://github.com/clojure/clojure/commit/bcb8e9a7aa0b0588b4872384256d86bf53d12f15 –

ответ

1

Запустите код OP, чтобы получить базовое время на моей машине. (Mac Pro 2009 2,66 ГГц Quad-Core 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 
+0

I ' У удивления что-то вроде 'n-conj' уже не существует, но я не мог его найти. –

+0

Примечание: Я запустил время на Clojure 1.7 Alpha 6, а версия '(in ...' была немного быстрее, около 27 миллисекунд, с 'n-conj' на 30 миллисекунд. Так что' n-conj' быстрее чем 1.6, но медленнее 1.7 '' ''. (apply ... 'все еще медленно, на 860 миллисекунд. –

Смежные вопросы