2013-05-14 17 views
8

Tôi đang thực hiện các hoạt động yếu tố khôn ngoan trên hai vectơ theo thứ tự 50.000 kích thước phần tử và có các vấn đề về hiệu suất không đạt yêu cầu (vài giây). Có bất kỳ vấn đề hiệu suất rõ ràng được thực hiện, chẳng hạn như sử dụng một cấu trúc dữ liệu khác nhau?Hiệu suất Clojure, vòng lặp lớn trên các vectơ lớn

(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))))) 

Trả lời

11

Hãy thử điều này:

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

Một số lưu ý:

  • map ping một hàm cho một số bộ sưu tập sử dụng một yếu tố từ mỗi như các đối số cho hàm - không cần phải interleavepartition cho việc này.
  • Nếu dữ liệu của bạn là 1 và 0, sau đó xor sẽ nhanh hơn so với sự khác biệt tuyệt đối

dụ Timed:

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

Sau nóng lên JVM ...

(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ạn nên xem xét việc áp dụng core.matrix nếu bạn quan tâm đến hiệu suất tốt cho các hoạt động vectơ lớn.

Cụ thể, thư viện vectorz-clj (triển khai core.matrix) có một số triển khai rất nhanh đối với các hoạt động vector phổ biến nhất với các giá trị double.

(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 

nghĩa là dưới 20ns mỗi cặp phần tử - đó là khá nhanh chóng: bạn muốn được cứng ép để đánh bại đó mà không cần mã mảng không quan trọng ở mức độ thấp.

+1

Ví dụ về mảng-fiddling (w/o kiểm tra cùng độ dài) để sử dụng trên 'int-array's:' (defn xor-sum [^ ints xs,^ints ys] (areduce xs i ret (int 0) (bỏ chọn-thêm ret (bit-xor (aget xs i) (aget ys i))))) ' ' –