2013-09-24 45 views

回答

2

对于初学者来说,range并不是一个数组,它会产生一个lazy-seq。

添加两个数字集合的最快方法可能是首先让它们在数组中,并且执行迭代循环而不是映射。

user> (time (let [a (int-array (range 1000000)) 
        b (int-array (range 1000000))] 
       (dotimes [i 1000000] 
       (aset a i (+ (aget b i) (aget a i)))) 
       a)) 
"Elapsed time: 771.100395 msecs" 
#<int[] [[email protected]> 
user> 

注意这仍然具有创造和两个范围调用实现懒seqs的开销,在实际性能,你很可能已经有越来越的累计工序之前建造的数据。

除非这是您的代码中的性能瓶颈,否则这样做会意味着您不应该首先使用clojure。使用clojure的优点是您可以获得高层次的不可变数据结构,从而实现透明且可并行的代码。一旦你下降到像数组这样的原始jvm类型,你就失去了这些优势(以换取更好的性能)。

+0

awesomethx !!!!! –

1

您可能会感兴趣Prismatic的"open-source array processing library HipHip, which combines Clojure's expressiveness with the fastest math Java has to offer"

我刚刚有了一个快速的去用它,它似乎能够提供表现力和性能之间的很好的平衡:

注:我使用Criterium的基准这个,因为它减少了一些问题,对标杆JVM。

(require '[criterium.core :refer [quick-bench]]) 

(quick-bench (doall (map + (range 1000000) (range 1000000)))) 
;=> "Execution time mean : 791.955406 ms" 

(require '[hiphip.int :as h]) 
(quick-bench (h/amap [x (h/amake [i 1000000] i) 
         y (h/amake [i 1000000] i)] 
       (+ x y))) 
;=> "Execution time mean : 20.540645 ms" 
相关问题