String concatenation in Ruby

The naïve way to concatenate a string in Ruby is to just use the addition (+) operator. This does makes sense as the ability to perform arithmatic operations on strings in Ruby is one of the things that helped me grow to love it initially, for example:

"hello" + "world" == "helloworld"
"hello" * 3 == "hellohellohello"

I use string concatenation an awful lot in my various Ruby project/experiments and I soon learned that the standard ‘+’ method is actually very slow. This is not much of a problem when calling it occasionally, but in a large loop it can make quite the difference to performance.

(For those that aren’t already aware, note that str_a += str_b is the same as str_a = str_a + str_b)

After a bit of research, it turns out that the ‘<<‘ method is far faster since it changes the original object, where as ‘+’ creates an entirely new string object. This can be seen by comparing the object_id’s:

input = "hello"
puts "Original ID: #{input.object_id}"

input << "world"
puts "ID after <</pre>
Outputs the following:

Original ID: 69876456811180
ID after <</pre>
While if we were to use the '+' operator:

input = "hello"
puts "Original ID: #{input.object_id}"

input += "world"
puts "ID after +=: #{input.object_id}"

A new object would be created:

Original ID: 69985983138420
ID after +=: 69985983138300

I wanted to compare all the different methods that can be used to concatenate a string, of which there are four (as far as I can tell). Below are the results of performing a string concatenation 10,000 times using various methods:

Method,Time Taken
str_a << str_b,1.5 ms str_a.concat(str_b),1.7 ms str_a += str_b,15.9 ms str_a = "#{str_a}#{str_b}",32 ms [/table] The latter two are understandably slower as they are creating a new object every time, but I'm surprised by how much slower it is to use string interpolation. << and string.concat seem to be roughly equivalent, but personally I think I'll continue to use << as it's prettier and fewer keystrokes.

Leave a Reply

Your email address will not be published. Required fields are marked *