2013-05-14 21 views
8

İki vektörde, boyut olarak 50.000 öğenin sırayla ve yetersiz performans sorunlarına (birkaç saniyeliğine) göre eleman işlemlerini gerçekleştiriyorum. Farklı bir veri yapısı kullanmak gibi belirgin performans sorunları var mı?Clojure performansı, büyük vektörler üzerinde büyük döngü

(defn boolean-compare 
    "Sum up 1s if matching 0 otherwise" 
    [proposal-img data-img] 
    (sum 
    (map 
    #(Math/abs (- (first %) (second %))) 
    (partition 2 (interleave proposal-img data-img))))) 

cevap

11

bu deneyin:

(apply + (map bit-xor proposal-img data-img))) 

bazı notlar: Birkaç koleksiyonlara

  • map ping bir işlev işleve argümanlar olarak her bir öğesini kullanan - interleave gerek ve Bunun için partition. Veri ise
  • 1'ler ve 0'lar, ardından xor mutlak farkın daha hızlı olacaktır

Zamanlı örnek: JVM ısındıktan sonra

(def data-img (repeatedly 50000 #(rand-int 2))) 
(def proposal-img (repeatedly 50000 #(rand-int 2))) 
(def sum (partial apply +)) 

...

(time (boolean-compare proposal-img data-img)) 
;=> "Elapsed time: 528.731093 msecs" 
;=> 24802 

(time (apply + (map bit-xor proposal-img data-img))) 
;=> "Elapsed time: 22.481255 msecs" 
;=> 24802 
5

Büyük vektör işlemleri için iyi performansla ilgileniyorsanız, core.matrix'u kabul etmelisiniz. Özellikle, vectorz-clj kitaplığının (bir core.matrix uygulaması), double değerleriyle en yaygın vektör işlemleri için çok hızlı uygulamalara sahip olması özellikle .

(def v1 (array (repeatedly 50000 #(rand-int 2)))) 
(def v2 (array (repeatedly 50000 #(rand-int 2)))) 

(time (let [d (sub v2 v1)] ;; take difference of two vectors 
    (.abs d)     ;; calculate absolute value (mutate d) 
    (esum d)))    ;; sum elements and return result 

=> "Elapsed time: 0.949985 msecs" 
=> 24980.0 

yani elemanların çifti başına 20ns altında - bu oldukça çabuk: Sabit düşük seviyeli dizisi-işe yaramaz kodu başvurmadan dövmek için baskı olurdu.

+1

Dizi içi çalışma (aynı uzunluk için değil) 'int-array's: '(def xor-sum [^ ints xs,^ints ys] (areduce xs i ret (int 0) için kullanılır.) (işaretlenmemiş-ekle ret (bit-xor (aget xs i) (aget ys i))))) ' ' –

İlgili konular