ac5j9g
Last Updated: December 05, 2017
·
31.96K
· bitsbyte
0791c9e78fae48e66b1f5dc6bb855440

+ or .concat, what is faster for appending string in Ruby?

Problem:

Yesterday I had to append around ~100-200K small strings (avg. length 7) to form a single large string . I had used + operator and it was very slow. To find a faster alternative I did following benchmarking experiment:

Solution:

TL;DR : use .concat instead of +

def bm_concat limit
  str = ""
  limit.times do
    str.concat("abcdefg")
  end
end

def bm_plus limit
  str = ""
  limit.times do
    str += "abcdefg"
  end
end

def diff t1, t2
  puts (t2-t1)
end

limit = ARGV[0]
which = ARGV[1]

puts "LIMIT: #{limit} , WHICH: #{which}"
if which == "plus"
  t = Time.now
  bm_plus limit.to_i
  t2 = Time.now
else
  t = Time.now
  bm_concat limit.to_i
  t2 = Time.now
end

diff(t,t2)

On replacing + with .concat in my originial code it was 4x faster!

Results of above code for various parameters are :

Picture

Say Thanks
Respond

3 Responses
Add your response

6836
4964bad1252f34c95f18c0862edb5c23

'+' created new object every time and '.concat' works on the same object.
Thats why 'concat' is faster and that's why you should not use it every time.
Tip: '<<' is an alias for '.concat'.

over 1 year ago ·
6952
0791c9e78fae48e66b1f5dc6bb855440

@korin learned it the hard way ! :)

over 1 year ago ·
22125
Picture 001 normal

Expanded this test to also include:
str = "#{str}abcdefg"

Seems to be even slower. ~18 seconds for plus vs. ~23 seconds for the #{str} notation doing 100000 concats. Tried about 10 times each so not super reliable but seems pretty consistent.

Further testing with other concatenations seems to show that str << "abcdefg" is even faster than .concat. But not by much. I would like to hear if anyone else can reproduce these results.

over 1 year ago ·