我在两个向量上执行元素操作,大小为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)))))
答案 0 :(得分:11)
试试这个:
(apply + (map bit-xor proposal-img data-img)))
一些注意事项:
map
ping函数到多个集合使用每个集合中的元素作为函数的参数 - 不需要interleave
和partition
。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
答案 1 :(得分: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
每对元素下 - 这很快:你很难在不诉诸低级数组代码的情况下击败它。