我想知道更有效的方式來只讀取基於特定長度的文件的字符串。我知道這是一種天真的做法:基於長度讀取行
len = 3
d = Array.new
t = File.open('d.txt').read
t.each_line do |x|
#+2 accounting for \n\r
if x.length == (len + 2)
d.push(x)
end
end
我想知道更有效的方式來只讀取基於特定長度的文件的字符串。我知道這是一種天真的做法:基於長度讀取行
len = 3
d = Array.new
t = File.open('d.txt').read
t.each_line do |x|
#+2 accounting for \n\r
if x.length == (len + 2)
d.push(x)
end
end
這具有許多問題:
len = 3
d = Array.new
t = File.open('d.txt').read
t.each_line do |x|
#+2 accounting for \n\r
if x.length == (len + 2)
d.push(x)
end
end
首先,整個文件被讀入,因爲File.open('d.txt').read
存儲器,然後使用each_line
分成行,最後是所希望的長度線抓獲。如果文件包含1,000,000行,並且只有一行是三個字符,則會浪費大量內存和CPU時間。
相反,寫這樣的:
len = 3
d = []
File.foreach('d.txt') do |x|
d << x if (x.chomp.length == len)
end
foreach
讀取每一行,保持換行符。 chomp
刪除換行符,以便您可以比較實際的行,而不需要結束行尾感謝chomp
到len
。然後,如果長度匹配,則該行將被附加到數組中。任何時候都不是整個文件在內存中,除非每行都是所需的長度。這樣可以節省內存,並且運行速度非常快,甚至可能比使用read
淹沒整個文件的原始速度更快,因爲如果文件足夠大,該過程可能需要一段時間。
這將與您的代碼一樣。
d = File.open("d.txt").lines.select{|l| l.chomp.length == len}
加上它是跨平臺的 – steenslag 2013-03-09 23:50:06