kikeda1104's blog

備忘録・技術に関することを書いています。(webエンジニア)

文字列の連結(`#+`, `#{}`)のベンチマーク

質問されてどうなのか知らなかったので、ベンチマークを取ってみた。

  - ruby 2.2.10
  - macOS
  - 3.3 GHz Intel Core i7

コード(sample利用)

require 'benchmark'

Benchmark.bm 10 do |r|
  r.report "#r+" do
    result = ''
    1000000.times do
      chr = [*'a'..'z'].sample
      result += chr
    end
  end

  r.report "#r{}" do
    result = ''
    1000000.times do
      chr = [*'a'..'z'].sample
      result = "#{result}#{chr}"
    end
  end
end

sampleの計算量を考慮していないので、sampleメソッドを利用しないコードでもベンチマークをとります。

コード(sample利用)

require 'benchmark'

Benchmark.bm 10 do |r|
  r.report "#r+" do
    result = ''
    100000.times do
      chr = "a"
      result += chr
    end
  end

  r.report "#r{}" do
    result = ''
    100000.times do
      chr = "a"
      result = "#{result}#{chr}"
    end
  end

  # おまけで測定(結果2回のみ)
  r.report "#r<<" do
    result = ''
    100000.times do
      chr = "a"
      result << chr
    end
  end
end

結果

# 単位は秒
# sample利用コード
                 user     system      total        real
#r+          0.930000   0.250000   1.180000 (  1.190557)
#r{}         1.130000   0.560000   1.690000 (  1.749810)

                 user     system      total        real
#r+          0.920000   0.210000   1.130000 (  1.127887)
#r{}         1.010000   0.360000   1.370000 (  1.395523)

                 user     system      total        real
#r+          0.970000   0.330000   1.300000 (  1.324458)
#r{}         1.010000   0.370000   1.380000 (  1.388045)

                 user     system      total        real
#r+          0.970000   0.270000   1.240000 (  1.246748)
#r{}         0.990000   0.320000   1.310000 (  1.319941)

                 user     system      total        real
#r+          0.870000   0.170000   1.040000 (  1.039002)
#r{}         1.180000   0.690000   1.870000 (  1.920898)

                 user     system      total        real
#r+          1.030000   0.390000   1.420000 (  1.459395)
#r{}         0.970000   0.300000   1.270000 (  1.284337)

                 user     system      total        real
#r+          0.890000   0.220000   1.110000 (  1.117645)
#r{}         1.020000   0.320000   1.340000 (  1.341777)

                 user     system      total        real
#r+          1.020000   0.430000   1.450000 (  1.470244)
#r{}         1.160000   0.550000   1.710000 (  1.927555)

# sample利用なしコード

                 user     system      total        real
#r+          0.810000   0.780000   1.590000 (  1.595337)
#r{}         0.890000   0.870000   1.760000 (  1.769899)

                 user     system      total        real
#r+          0.790000   0.740000   1.530000 (  1.542483)
#r{}          0.950000   1.030000   1.980000 (  2.017400)

                 user     system      total        real
#r+          0.800000   0.780000   1.580000 (  1.594527)
#r{}         0.910000   1.020000   1.930000 (  2.001948)

                 user     system      total        real
#r+          0.850000   0.840000   1.690000 (  1.733741)
#r{}         0.920000   0.950000   1.870000 (  1.893551)

                 user     system      total        real
#r+          0.800000   0.780000   1.580000 (  1.585265)
#r{}         0.910000   0.890000   1.800000 (  1.809907)

                 user     system      total        real
#r+          0.780000   0.750000   1.530000 (  1.560372)
#r{}         0.910000   0.930000   1.840000 (  1.838491)

                 user     system      total        real
#r+          0.790000   0.750000   1.540000 (  1.552678)
#r{}         0.920000   0.950000   1.870000 (  1.874736)

                 user     system      total        real
#r+          0.770000   0.740000   1.510000 (  1.545361)
#r{}         0.920000   1.030000   1.950000 (  2.017822)

# おまけ
                 user     system      total        real
#r+          0.810000   0.800000   1.610000 (  1.654600)
#r{}         0.970000   1.090000   2.060000 (  2.197110)
#r<<         0.020000   0.010000   0.030000 (  0.019684)

                 user     system      total        real
#r+          0.810000   0.780000   1.590000 (  1.606184)
#r{}         0.950000   1.020000   1.970000 (  1.994647)
#r<<         0.030000   0.000000   0.030000 (  0.035348)

ベンチマーク結果

#+ 0.870000 -  1.030000
#{} 0.990000 -  1.180000

#+ 0.770000 - 0.850000
#{} 0.890000 -  0.920000
#<< 0.020000 - 0.030000

結論しては、ruby 2.2.10では、#r+#{}では、#+が早いと言えました。

以上です。