Do you know if using double quotes instead of single quotes in ruby decreases performance in any meaningful way in ruby 1.8 and 1.9.
so if I type
qu
There's one you all missed.
HERE doc
try this
require 'benchmark'
mark = <<EOS
a string
EOS
n = 1000000
Benchmark.bm do |x|
x.report("assign here doc") {n.times do; mark; end}
end
It gave me
`asign here doc 0.141000 0.000000 0.141000 ( 0.140625)`
and
'concat single quotes 1.813000 0.000000 1.813000 ( 1.843750)'
'concat double quotes 1.812000 0.000000 1.812000 ( 1.828125)'
so it's certainly better than concat and writing all those puts.
I would like to see Ruby taught more along the lines of a document manipulation language.
After all, don't we really do that in Rails, Sinatra, and running tests?
$ 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.
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.
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)
Double quotes take twice as many key strikes to type than single quotes. I'm always in a hurry. I use single quotes. :) And yes, I consider that a "performance gain". :)
~ > ruby -v
jruby 1.6.7 (ruby-1.8.7-p357) (2012-02-22 3e82bc8) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_37) [darwin-x86_64-java]
~ > cat qu.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("concat single") { n.times do; 'a string ' + 'b string'; end}
x.report("concat double") { n.times do; "a string " + "b string"; end}
end
~ > ruby qu.rb
user system total real
assign single 0.186000 0.000000 0.186000 ( 0.151000)
assign double 0.062000 0.000000 0.062000 ( 0.062000)
concat single 0.156000 0.000000 0.156000 ( 0.156000)
concat double 0.124000 0.000000 0.124000 ( 0.124000)