I am performing element-wise operations on two vectors on the order of 50,000 elements in size, and having unsatisfactory performance issues (a few seconds). Are there any obvious performance issues to be made, such as using a different data structure?
我在两个向量上执行元素操作,大小为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)))))
2 个解决方案
#1
11
Try this:
尝试这个:
(apply + (map bit-xor proposal-img data-img)))
Some notes:
一些说明:
-
map
ping a function to several collections uses an element from each as the arguments to the function - no need tointerleave
andpartition
for this. - 将函数映射到多个集合使用每个集合中的元素作为函数的参数 - 不需要为此进行交错和分区。
- If your data is 1's and 0's, then
xor
will be faster than absolute difference - 如果您的数据是1和0,那么xor将比绝对差异更快
Timed example:
定时的例子:
(def data-img (repeatedly 50000 #(rand-int 2)))
(def proposal-img (repeatedly 50000 #(rand-int 2)))
(def sum (partial apply +))
After warming up the JVM...
热身后的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
#2
5
You should look at adopting core.matrix if you are interested in good performance for large vector operations.
如果您对大型矢量操作的良好性能感兴趣,您应该考虑采用core.matrix。
In particular, the vectorz-clj library (a core.matrix implementation) has some very fast implementations for most common vector operations with double
values.
特别是,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
i.e. under 20ns
per pair of elements - that's pretty quick: you'd be hard pressed to beat that without resorting to low-level array-fiddling code.
即每对元素不到20ns - 这很快:你很难在不诉诸低级阵列代码的情况下击败它。
#1
11
Try this:
尝试这个:
(apply + (map bit-xor proposal-img data-img)))
Some notes:
一些说明:
-
map
ping a function to several collections uses an element from each as the arguments to the function - no need tointerleave
andpartition
for this. - 将函数映射到多个集合使用每个集合中的元素作为函数的参数 - 不需要为此进行交错和分区。
- If your data is 1's and 0's, then
xor
will be faster than absolute difference - 如果您的数据是1和0,那么xor将比绝对差异更快
Timed example:
定时的例子:
(def data-img (repeatedly 50000 #(rand-int 2)))
(def proposal-img (repeatedly 50000 #(rand-int 2)))
(def sum (partial apply +))
After warming up the JVM...
热身后的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
#2
5
You should look at adopting core.matrix if you are interested in good performance for large vector operations.
如果您对大型矢量操作的良好性能感兴趣,您应该考虑采用core.matrix。
In particular, the vectorz-clj library (a core.matrix implementation) has some very fast implementations for most common vector operations with double
values.
特别是,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
i.e. under 20ns
per pair of elements - that's pretty quick: you'd be hard pressed to beat that without resorting to low-level array-fiddling code.
即每对元素不到20ns - 这很快:你很难在不诉诸低级阵列代码的情况下击败它。