2011-09-26 26 views
2

我正在ruby中運行一個漂亮的內存密集型程序,它最初速度很快,然後隨着內存利用率的增加而變慢。這個程序有兩個階段:(1)在內存中建立一個大的hash: string => list,(2)在散列上做一些計算。減速發生在階段1.爲內存密集型程序製作紅寶石更快

爲什麼會發生這種情況?是否有更多的垃圾收集器的調用?或者是紅寶石交換內存到磁盤?

無論哪種情況,我可以採取哪些配置來加快速度?例如,我可以增加堆大小或允許ruby使用的最大內存量?我沒有在手冊頁中看到任何內容。

+1

如果您提供更多細節,您可能會得到更好的答案。例如,你的操作系統是否說你是分頁? –

+1

@David Nehme - 我如何檢查我的操作系統是否說我是分頁?我在OSX上。 – dsg

回答

1

對於大型數據集,我發現ruby的速度真的很慢,我處理它的方式是運行ruby 1.9.2或更高版本,或者甚至在可能的情況下運行jruby。如果這還不夠,當遍歷非常大的數據集時,我通常會回到mapreduce範例,這樣我只需要一次在內存中保留一行。對於與建築哈希一個類似於您的問題,我只希望有一個Ruby程序發出到$ stdout中,鏈接或輸出轉移到一個文件:

$ ruby build_csv.rb > items.csv 
$ cat items.csv 
foo,23 
foo,17 
bar,42 

則具有可以讀取的第二個程序數據結構散列成散列

@hsh = Hash.new { |hash, key| hash[key] = [] } 
File.open("items.csv").each_line do |l| 
    k,v = l.split(',') 
    @hsh[k] << v 
end 

如果使用CSV庫,以前的程序當然可以更快。無論如何,它會在hsh中讀到這樣的內容。

@hsh => {"foo"=>[23, 17], "bar"=>[42]} 

分裂的問題分成許多小程序真是讓人對速度的差異,因爲較少被保存在內存中,如果散列操作只需要在一個單一的重點工作,則很容易寫的那部分作爲剛剛讀取的東西,直到找到新密鑰,在最後一個密鑰上產生輸出,然後繼續使用新密鑰,這與第一輪非常相似。通過在文件中分割和生成中間結果來保持內存的使用,實際上可以大大加快進程速度。如果您可以分割您的數據,您還可以在shell中或通過使用線程立即運行多個階段1 /映射作業。