In micro-benchmarking, this change performs within margin of error of
the existing code but saves a string allocation each time the method is
called (assuming the quote strings in the old code were frozen).
```
begin
require "bundler/inline"
rescue LoadError => e
$stderr.puts "Bundler version 1.10 or later is required. Please update
your Bundler"
raise e
end
gemfile(true) do
source "https://rubygems.org"
gem "benchmark-ips"
end
def allocate_count
GC.disable
before = ObjectSpace.count_objects
yield
after = ObjectSpace.count_objects
after.each { |k,v| after[k] = v - before[k] }
after[:T_HASH] -= 1 # probe effect - we created the before hash.
GC.enable
result = after.reject { |k,v| v == 0 }
GC.start
result
end
interpolated = "hi"
puts "'"' + interpolated + '"'"
puts allocate_count { 1000.times { '"' + interpolated + '"' } }
puts "%(\"\#{interpolated}\")"
puts allocate_count { 1000.times { %("#{interpolated}") } }
puts "\"\#{interpolated}\""
puts allocate_count { 1000.times { "\"#{interpolated}\"" } }
Benchmark.ips do |x|
x.report("'"' + interpolated + '"'") { '"' + interpolated + '"' }
x.report("%(\"\#{interpolated}\")") { %("#{interpolated}") }
x.report("\"\#{interpolated}\"") { "\"#{interpolated}\"" }
x.compare!
end
```ruby
```
' + interpolated + '
{:FREE=>-1892, :T_STRING=>2052}
%("#{interpolated}")
{:FREE=>-1001, :T_STRING=>1000}
"#{interpolated}"
{:FREE=>-1001, :T_STRING=>1000}
Warming up --------------------------------------
' + interpolated + ' 81.706k i/100ms
%("#{interpolated}") 106.128k i/100ms
"#{interpolated}" 137.855k i/100ms
Calculating -------------------------------------
' + interpolated + ' 3.892M (±23.2%) i/s - 17.975M in 5.007068s
%("#{interpolated}") 3.722M (±17.3%) i/s - 17.830M in 5.022549s
"#{interpolated}" 3.725M (±15.0%) i/s - 18.059M in 5.023493s
Comparison:
' + interpolated + ': 3892392.6 i/s
"#{interpolated}": 3725385.8 i/s - same-ish: difference falls within error
%("#{interpolated}"): 3722401.7 i/s - same-ish: difference falls within error
```