2013-08-26 61 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

這是一個答案或評論? –