特定の長さに基づいてファイルの文字列のみを読み取るより効率的な方法を考えていました。私はこれが素朴なアプローチであることを知っています:
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
これはあなたのコードと同じことをします。
d = File.open("d.txt").lines.select{|l| l.chomp.length == len}
これにはいくつかの問題があります。
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行で構成されていて、1つだけが3文字の長さである場合、多くの無駄なメモリとCPU時間が発生します。
代わりに、次のように記述します。
len = 3
d = []
File.foreach('d.txt') do |x|
d << x if (x.chomp.length == len)
end
foreach
改行を維持しながら、各行を読み取ります。chomp
改行を削除して、のおかげで行末なしで実際の行をと比較できるようchomp
にしlen
ます。次に、長さが一致すると、行が配列に追加されます。すべての行が目的の長さでない限り、ファイル全体がメモリに保存されることはありません。read
これによりメモリが節約され、ファイル全体が十分に大きい場合、そのプロセスに時間がかかる可能性があるため、ファイル全体を丸呑みするために使用された元のファイルよりも非常に高速に実行されます。