とりあえずbenchmark-ips
を用いてベンチマーク取ってみました。
追記: to_csv
が遅い理由がわかったのでCSV.newを使ってみるものを追加
ruby
1require 'benchmark/ips'
2require 'csv'
3array = Array.new(100_000){|i| [i, rand]}
4
5Benchmark.ips do |x|
6 x.report("to_csv") { array.map{|i| i.to_csv}.join }
7 x.report("join") { array.map{|ary| ary.join ','}.join }
8 x.report("CSV"){
9 csv = CSV.new ""
10 array.each{|it| csv << it }
11 csv.string
12 }
13 # CSVではないが参考までにMarshal.dump (Rubyのデータ吐き出し系では最速のハズ)
14 x.report("marshal"){ Marshal.dump array }
15 x.compare!
16end
結果は
Calculating -------------------------------------
to_csv 0.218 (± 0.0%) i/s - 2.000 in 9.170508s
join 5.510 (± 0.0%) i/s - 28.000 in 5.094200s
CSV 2.628 (± 0.0%) i/s - 14.000 in 5.329939s
marshal 8.665 (± 0.0%) i/s - 44.000 in 5.081920s
Comparison:
marshal: 8.7 i/s
join: 5.5 i/s - 1.57x slower
CSV: 2.6 i/s - 3.30x slower
to_csv: 0.2 i/s - 39.68x slower
と、「配列を回す」というよりは「to_csv」が遅い
という結果になりました。
to_csv
は1行ごとに
ruby
1(CSV.new("") << row).string
を行うため
複数行を手に入れるために複数回繰り返すのは完全に無駄です。