New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace interpolated interpolation with cleaner method #965

Merged
merged 1 commit into from Oct 26, 2017

Conversation

Projects
None yet
2 participants
@oniofchaos
Contributor

oniofchaos commented Oct 25, 2017

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
' + 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

results of benchmark.rb

                                         Haml |     ERB |  Erubis |
-------------------------------------------------------------------
Cached                                  0.094 |   0.083 |   0.073 |
ActionView                             16.937 |  11.760 |         |
ActionView with deep partials          38.459 |  40.428 |         |

compared to current master

                                         Haml |     ERB |  Erubis |
-------------------------------------------------------------------
Cached                                  0.174 |   0.420 |   0.224 |
ActionView                             21.360 |  11.631 |         |
ActionView with deep partials          43.563 |  39.238 |         |
@amatsuda

This comment has been minimized.

Show comment
Hide comment
@amatsuda

amatsuda Oct 26, 2017

Member

@oniofchaos Could you squash your commits, resolve the conflict in CHANGELOG, then push -f please?

Member

amatsuda commented Oct 26, 2017

@oniofchaos Could you squash your commits, resolve the conflict in CHANGELOG, then push -f please?

Replace interpolated interpolation with cleaner method
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
```
@oniofchaos

This comment has been minimized.

Show comment
Hide comment
@oniofchaos

oniofchaos Oct 26, 2017

Contributor

@amatsuda done!

Contributor

oniofchaos commented Oct 26, 2017

@amatsuda done!

@amatsuda amatsuda merged commit 28e9222 into haml:master Oct 26, 2017

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
@amatsuda

This comment has been minimized.

Show comment
Hide comment
@amatsuda

amatsuda Oct 26, 2017

Member

Thanks!

Member

amatsuda commented Oct 26, 2017

Thanks!

@oniofchaos oniofchaos deleted the q-centrix:eval-interpolated-change branch Oct 30, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment