8

我正在对大小约为 50,000 个元素的两个向量执行逐元素操作,并且存在不令人满意的性能问题(几秒钟)。是否存在任何明显的性能问题,例如使用不同的数据结构?

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

2 回答 2

11

尝试这个:

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

一些注意事项:

  • map将一个函数 ping 到几个集合使用每个集合中的一个元素作为函数的参数 - 不需interleave要这样做partition
  • 如果您的数据是 1 和 0,那么xor将比绝对差异更快

定时示例:

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

预热 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
于 2013-05-14T01:36:50.230 回答
5

如果您对大型向量操作的良好性能感兴趣,您应该考虑采用core.matrix 。

特别是,vectorz-clj库(一个 core.matrix 实现)对于最常见的带有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

即在20ns每对元素下 - 这非常快:如果不诉诸低级数组摆弄代码,你将很难击败它。

于 2013-05-14T13:18:34.490 回答