我想找到在 clojure 中生成非惰性数字列表的最快方法。目前我正在使用以下内容:
(doall (take 5000000 (iterate inc 5000000000)))
生成 50 亿到 50.05 亿之间的非惰性数字列表。有没有更快的方法来做到这一点?谢谢
(ps 我知道使用列表来存储数字序列是次优的。但是我将其用作Shen.java编译器的基准)
我想找到在 clojure 中生成非惰性数字列表的最快方法。目前我正在使用以下内容:
(doall (take 5000000 (iterate inc 5000000000)))
生成 50 亿到 50.05 亿之间的非惰性数字列表。有没有更快的方法来做到这一点?谢谢
(ps 我知道使用列表来存储数字序列是次优的。但是我将其用作Shen.java编译器的基准)
其实,doall
效果很好。您的示例的唯一问题是iterate
功能缓慢。您应该使用范围而不是它:
(doall (range 5000000000 5005000000))
range
非常快。它是懒惰的,但它经过优化,并以块的形式生成数字。
以下是使用criteriumiterate
获得的基准结果:run
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
如您所见,range
比iterate
这里快 2.5 倍。
在我的 PC 上,生成所有 5000000 个数字只需不到一秒钟的时间,但有一些技巧可以让它更快地工作。
例如,您可以在单独的线程中运行生成:
(let [numbers (range 5000000000 5005000000)]
(future (dorun numbers))
...)
它不会使生成速度更快,但您可以在完全实现之前立即使用您的序列。
doall通常是您需要的。但是“最快”是什么意思?在性能方面或在编码方面最快?