Project

General

Profile

Actions

Misc #10560

open

confusion between x=x+y, x+=y, x.concat(y) and y.each{|z| x<<z}

Added by mpapis (Michal Papis) about 10 years ago. Updated almost 7 years ago.

Status:
Assigned
Assignee:
[ruby-core:66621]

Description

while discussing a ticket I have noticed that there is no documentation for +=

I was expecting += to behave as concat but instead it behaves as x=x+y which for every operation clones the array and updates the variable with new value so it behaves similarly to x=x.dup.concat(y) and is slightly faster, but using plane x.concat(y) is a lot faster from both each<< and +=

I would either like to get:

  • updated docs that describe concept of += and show the difference from concat
  • or change += to use concat which is faster - and add docs ;) (I would expect += to use concat when available)

here is a test:

require 'benchmark'

rep = 10_000

Benchmark.bmbm do |x|
  {
    1..25 => [],
    "a".."z" => "",
  }.each do |base, storage|

    base = base.to_a
    basej = base
    class_name = storage.class.to_s

    x.report(class_name+'#concat') do
      a = storage.dup
      basej = base.join if storage == ""
      rep.times { a.concat(basej) }
    end

    x.report(class_name+'#<<') do
      a = storage.dup
      basej = base.join if storage == ""
      rep.times { base.each { |e| a << e } }
    end

    x.report(class_name+'#+=') do
      a = storage.dup
      basej = base.join if storage == ""
      rep.times { a += basej }
    end

    x.report(class_name+'#dup.concat') do
      a = storage.dup
      basej = base.join if storage == ""
      rep.times { a = a.dup.concat(basej) }
    end

  end
end

and here are results on my machine:

                        user     system      total        real
Array#concat        0.000000   0.000000   0.000000 (  0.001422)
Array#<<            0.020000   0.000000   0.020000 (  0.014356)
Array#+=            1.270000   0.230000   1.500000 (  1.498558)
Array#dup.concat    2.720000   0.190000   2.910000 (  2.915701)
String#concat       0.000000   0.000000   0.000000 (  0.001072)
String#<<           0.030000   0.000000   0.030000 (  0.025828)
String#+=           0.130000   0.010000   0.140000 (  0.135143)
String#dup.concat   0.210000   0.020000   0.230000 (  0.227470)
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0