生成非惰性数字列表的最快方法

时间:2013-08-26 08:55:22

标签: clojure

我想找到在clojure中生成非惰性数字列表的最快方法。目前我正在使用以下内容:

(doall (take 5000000 (iterate inc 5000000000)))

生成50亿到50.05亿之间的非惰性数字列表。有没有更快的方法来做到这一点?谢谢

(p.s。我知道使用列表来存储数字序列是次优的。但是我使用它作为 Shen.java 编译器的基准)

2 个答案:

答案 0 :(得分:2)

实际上,doall效果很好。您的示例唯一的问题是慢iterate函数。您应该使用range代替它:

(doall (range 5000000000 5005000000))

range非常快。它是懒惰的,但它已经过优化,并且会以块的形式生成数字。

以下是使用criterium获得的iteraterun的基准测试结果:

user=> (quick-bench (doall (take 5000 (iterate inc 5000000))))
Evaluation count : 180 in 6 samples of 30 calls.
             Execution time mean : 3.175749 ms
    Execution time std-deviation : 1.179449 ms
   Execution time lower quantile : 2.428681 ms ( 2.5%)
   Execution time upper quantile : 4.735748 ms (97.5%)
                   Overhead used : 14.758153 ns

user=> (quick-bench (doall (range 5000000 5005000)))
Evaluation count : 672 in 6 samples of 112 calls.
             Execution time mean : 1.253228 ms
    Execution time std-deviation : 350.301594 µs
   Execution time lower quantile : 845.026223 µs ( 2.5%)
   Execution time upper quantile : 1.582950 ms (97.5%)
                   Overhead used : 14.758153 ns

如您所见,rangeiterate快2.5倍。

在我的电脑上生成所有5000000个数字需要不到一秒的时间,但是有一些技巧可以让它更快地工作。

例如,您可以在单独的线程中运行生成:

(let [numbers (range 5000000000 5005000000)]
  (future (dorun numbers))
  ...)

它不会让生成更快,但是你可以在它完全实现之前立即使用你的序列。

答案 1 :(得分:0)

doall 通常就是您所需要的。但你说“最快”是什么意思?在性能或编码环境中最快?