Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a performance gain in using single quotes vs double quotes in ruby?

People also ask

What is the difference between single quote and double quote in Ruby?

The basic difference between these two methods is Single quotes can not hold/print escape sequences directly, while double quotes can. i.e. Double quoted strings are used for String Interpolation in Ruby.

Should I use single or double quotes programming?

Both single (' ') and double (" ") quotes are used to represent a string in Javascript. Choosing a quoting style is up to you and there is no special semantics for one style over the other. Nevertheless, it is important to note that there is no type for a single character in javascript, everything is always a string!

Is there any reason to use double or single quotes?

If you need to put a quotation inside your first quotation, use the opposite type of quotation marks to surround it. That's single quotation marks in American English. Double quotation marks can also be used to show sarcasm or to identify words used as words instead of for their meaning.

Can you use single quotes in Ruby?

Best practice. As most of the Ruby Linters suggest use single quote literals for your strings and go for the double ones in the case of interpolation/escaping sequences.


Summary: no speed difference; this great collaborative Ruby style guide recommends being consistent. I now use 'string' unless interpolation is needed (option A in the guide) and like it, but you will typically see more code with "string".

Details:

Theoretically, it can make a difference when your code is parsed, but not only should you not care about parse time in general (negligible compared to execution time), you won't be able to find a significant difference in this case.

The important thing is that when is gets executed it will be exactly the same.

Benchmarking this only shows a lack of understanding of how Ruby works. In both cases, the strings will get parsed to a tSTRING_CONTENT (see the source in parse.y). In other words, the CPU will go through the exact same operations when creating 'string' or "string". The exact same bits will flip the exact same way. Benchmarking this will only show differences that are not significant and due to other factors (GC kicking in, etc.); remember, there can't be any difference in this case! Micro benchmarks like these are difficult to get right. See my gem fruity for a decent tool for this.

Note that if there is interpolation of the form "...#{...}...", this gets parsed to a tSTRING_DBEG, a bunch of tSTRING_DVAR for the each expression in #{...} and a final tSTRING_DEND. That's only if there is interpolation, though, which is not what the OP is about.

I used to suggest you use double quotes everywhere (makes it easier to actually add that #{some_var} later on), but I now use single quotes unless I need interpolation, \n, etc... I like it visually and it's slightly more explicit, since there's no need to parse the string to see if it contains any expression.


$ ruby -v
ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.0.0]

$ cat benchmark_quotes.rb
# As of Ruby 1.9 Benchmark must be required
require 'benchmark'

n = 1000000
Benchmark.bm(15) do |x|
  x.report("assign single") { n.times do; c = 'a string'; end}
  x.report("assign double") { n.times do; c = "a string"; end}
  x.report("concat single") { n.times do; 'a string ' + 'b string'; end}
  x.report("concat double") { n.times do; "a string " + "b string"; end}
end

$ ruby benchmark_quotes.rb 

                      user     system      total        real
assign single     0.110000   0.000000   0.110000 (  0.116867)
assign double     0.120000   0.000000   0.120000 (  0.116761)
concat single     0.280000   0.000000   0.280000 (  0.276964)
concat double     0.270000   0.000000   0.270000 (  0.278146)

Note: I've updated this to make it work with newer Ruby versions, and cleaned up the header, and run the benchmark on a faster system.

This answer omits some key points. See especially these other answers concerning interpolation and the reason there is no significant difference in performance when using single vs. double quotes.


No one happened to measure concatenation vs interpolation though:

$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i686-darwin9.6.2]
$ cat benchmark_quotes.rb
require 'benchmark'
n = 1000000
Benchmark.bm do |x|
  x.report("assign single") { n.times do; c = 'a string'; end}
  x.report("assign double") { n.times do; c = "a string"; end}
  x.report("assign interp") { n.times do; c = "a string #{'b string'}"; end}
  x.report("concat single") { n.times do; 'a string ' + 'b string'; end}
  x.report("concat double") { n.times do; "a string " + "b string"; end}
end

$ ruby -w benchmark_quotes.rb 
      user     system      total        real
assign single  2.600000   1.060000   3.660000 (  3.720909)
assign double  2.590000   1.050000   3.640000 (  3.675082)
assign interp  2.620000   1.050000   3.670000 (  3.704218)
concat single  3.760000   1.080000   4.840000 (  4.888394)
concat double  3.700000   1.070000   4.770000 (  4.818794)

Specifically, note assign interp = 2.62 vs concat single = 3.76. As icing on the cake, I also find interpolation to be more readable than 'a' + var + 'b' especially with regard to spaces.


No difference - unless you're using #{some_var} style string interpolation. But you only get the performance hit if you actually do that.

Modified from Zetetic's example:

require 'benchmark'
n = 1000000
Benchmark.bm do |x|
  x.report("assign single") { n.times do; c = 'a string'; end}
  x.report("assign double") { n.times do; c = "a string"; end}
  x.report("assign interp") { n.times do; c = "a #{n} string"; end}  
  x.report("concat single") { n.times do; 'a string ' + 'b string'; end}
  x.report("concat double") { n.times do; "a string " + "b string"; end}
  x.report("concat interp") { n.times do; "a #{n} string " + "b #{n} string"; end}
end

output

               user       system     total    real
assign single  0.370000   0.000000   0.370000 (  0.374599)
assign double  0.360000   0.000000   0.360000 (  0.366636)
assign interp  1.540000   0.010000   1.550000 (  1.577638)
concat single  1.100000   0.010000   1.110000 (  1.119720)
concat double  1.090000   0.000000   1.090000 (  1.116240)
concat interp  3.460000   0.020000   3.480000 (  3.535724)