Rubyの組み込みベンチマークを使用してベンチマークテストを実行し、最速の選択肢を見つける必要があります。
ただし、経験から、ファイルを「スラップ」する、つまり一度にすべてを読み込むことは、IO.foreach
またはFile.foreach
でループを使用するよりも速くないことがわかりました。これは、Rubyと基盤となるOSが読み取りの発生時にファイルのバッファリングを実行し、ディスクから直接ではなくメモリからループを発生させるためです。foreach
のようにラインターミネータを削除しないので、またはsplit
を追加する必要があります。または、読み込まれた行を変更する場合は、次のように入力します。chomp
chomp!
File.foreach('/path/to/file') do |li|
puts li.chomp
end
また
File.foreach('/path/to/file') do |li|
li.chomp!
puts li
end
また、丸呑みにはスケーラブルではないという問題があります。メモリよりも大きいファイルを読み取ろうとして、マシンをひざまずかせてしまう可能性がありますが、行ごとに読み取ることはできません。
パフォーマンスの数値は次のとおりです。
#!/usr/bin/env ruby
require 'benchmark'
require 'fileutils'
FILENAME = 'test.txt'
LOOPS = 1
puts "Ruby Version: #{RUBY_VERSION}"
puts "Filesize being read: #{File.size(FILENAME)}"
puts "Lines in file: #{`wc -l #{FILENAME}`.split.first}"
Benchmark.bm(20) do |x|
x.report('read.split') { LOOPS.times { File.read(FILENAME).split("\n") }}
x.report('read.lines.chomp') { LOOPS.times { File.read(FILENAME).lines.map(&:chomp) }}
x.report('readlines.map.chomp1') { LOOPS.times { File.readlines(FILENAME).map(&:chomp) }}
x.report('readlines.map.chomp2') { LOOPS.times { File.readlines(FILENAME).map{ |s| s.chomp } }}
x.report('foreach.map.chomp1') { LOOPS.times { File.foreach(FILENAME).map(&:chomp) }}
x.report('foreach.map.chomp2') { LOOPS.times { File.foreach(FILENAME).map{ |s| s.chomp } }}
end
そして結果:
Ruby Version: 1.9.3
Filesize being read: 42026131
Lines in file: 465440
user system total real
read.split 0.150000 0.060000 0.210000 ( 0.213365)
read.lines.chomp 0.470000 0.070000 0.540000 ( 0.541266)
readlines.map.chomp1 0.450000 0.090000 0.540000 ( 0.535465)
readlines.map.chomp2 0.550000 0.060000 0.610000 ( 0.616674)
foreach.map.chomp1 0.580000 0.060000 0.640000 ( 0.641563)
foreach.map.chomp2 0.620000 0.050000 0.670000 ( 0.662912)
今日のマシンでは、42MBのファイルをRAMにかなり安全に読み込むことができます。一部の本番ホストのメモリに収まらないファイルよりもはるかに大きいファイルを見たことがあります。速度は遅くなりますがforeach
、十分なメモリがない場合は、すべてのメモリを吸い上げてマシンをひざまずかせることもありません。
Ruby 1.9.3ではmap(&:chomp)
、古い形式のの代わりにメソッドを使用する方map { |s| s.chomp }
がはるかに高速です。これは古いバージョンのRubyには当てはまらなかったので、エンプターに注意してください。
また、上記のすべてが私の数年前のMacProで1秒未満でデータを処理したことに注意してください。全体として、ロード速度を心配するのは時期尚早の最適化であり、本当の問題はデータがロードされた後に何が行われるかということです。