2013-08-26 33 views
0

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

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

生成一个非惰性列表,数量在50亿到5050亿之间。有没有更快的方法来做到这一点?由于

(PS我知道,使用列表存储编号顺序是次优的。但是我用这作为Shen.java编译器的基准)

+0

你想快速的方法来填充一个缓慢的数据结构? –

+2

您可以指定'range'的开始和结束(和步骤)。 –

+0

@AlisterLee:最快的方式不是很快。我知道我的做法是不是最快的方法来填充列表 – artella

回答

2

其实,doall的伟大工程。你的例子唯一的问题是缓慢的iterate函数。您应该改用range它:

(doall (range 5000000000 5005000000)) 

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

这里是iteraterun基准测试结果用criterium得出:

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倍。

在我的电脑需要不到一秒钟产生的所有500万个的数字,但也有一些技巧,使它更快的工作。

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

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

它不会让一代快,但你就可以立即使用你的序列之前,这将是完全-realized。

+0

非常感谢。 Shen.java最初是做在4S而使用Clojure的迭代正在采取7S,我知道,我必须一直在做Clojure的版本太慢! – artella

+1

严格来说,这个答案是关于生成和实现[**序列**](http://clojure.org/sequences)而不是创建[** list **](http://clojure.org/data_structures #Data%20Structures-Lists%20(IPersistentList))如标题中所述。对于一个列表,你需要做一些类似'(到'()(范围5000000000 5005000000))'(或'(到'()(范围5005000000 5000000000 -1)')以保持顺序。但正如我从上下文中了解的那样,这不是你在这里需要的。 –

+0

@PawełŁoziński谢谢是的,我想要名单。现在clojure正在采取与Shen.java相似的4秒。 – artella

0

的doall通常是什么你需要。但是,“最快”是什么意思?在性能的情况下还是在编码方面最快?

+3

这是一个答案或评论? –