diff options
author | Dillon Welch <daw0328@gmail.com> | 2017-10-23 11:55:12 -0700 |
---|---|---|
committer | Dillon Welch <daw0328@gmail.com> | 2017-10-23 11:55:12 -0700 |
commit | a5c9f24603da478366a7fa1a1279f13501e30bbe (patch) | |
tree | c9f1473b8d9799c7b9a983facbc310093c331233 /actionpack/test/dispatch/runner_test.rb | |
parent | 4a8f4124bf019fe87989aeccc99d812fea25eb80 (diff) | |
download | rails-a5c9f24603da478366a7fa1a1279f13501e30bbe.tar.gz rails-a5c9f24603da478366a7fa1a1279f13501e30bbe.tar.bz2 rails-a5c9f24603da478366a7fa1a1279f13501e30bbe.zip |
Performance improvements for acts_like? method.
activesupport/lib/active_support/core_ext/object/acts_like.rb
acts_like?
Add a case statement to use direct symbols instead of string
interpolation for the three scenarios I found in the Rails codebase:
time, date, and string.
For time/date/string, this change prevents two string allocations for
each time the method is called and speeds up the method by ~2.7x. For
other arguments, there is no memory difference and performance
difference is within margin of error.
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 "rails", github: "rails/rails"
gem "arel", github: "rails/arel"
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
class Object
def fast_acts_like?(duck)
case duck
when :time
respond_to? :acts_like_time?
when :date
respond_to? :acts_like_date?
when :string
respond_to? :acts_like_string?
else
respond_to? :"acts_like_#{duck}?"
end
end
end
puts
puts " acts_like? ".center(80, '=')
puts
obj = ''.freeze
%i(time date string super_hacka).each do |type|
puts " #{type} ".center(80, '=')
puts " Memory Usage ".center(80, "=")
puts
puts "value.acts_like?"
puts allocate_count { 1000.times { obj.acts_like?(type) } }
puts "value.fast_acts_like?"
puts allocate_count { 1000.times { obj.fast_acts_like?(type) } }
puts
puts " Benchmark.ips ".center(80, "=")
puts
Benchmark.ips do |x|
x.report("acts_like?") { obj.acts_like?(type) }
x.report("fast_acts_like?") { obj.fast_acts_like?(type) }
x.compare!
end
end
================================== acts_like? ==================================
===================================== time =====================================
================================= Memory Usage =================================
value.acts_like?
{:FREE=>-1983, :T_STRING=>2052, :T_IMEMO=>1}
value.fast_acts_like?
{:FREE=>-1}
================================ Benchmark.ips =================================
Warming up --------------------------------------
acts_like? 104.281k i/100ms
fast_acts_like? 155.523k i/100ms
Calculating -------------------------------------
acts_like? 1.688M (±10.7%) i/s - 8.342M in 5.003804s
fast_acts_like? 4.596M (±12.1%) i/s - 22.551M in 5.000124s
Comparison:
fast_acts_like?: 4596162.4 i/s
acts_like?: 1688163.8 i/s - 2.72x slower
===================================== date =====================================
================================= Memory Usage =================================
value.acts_like?
{:FREE=>-2001, :T_STRING=>2000}
value.fast_acts_like?
{:FREE=>-1}
================================ Benchmark.ips =================================
Warming up --------------------------------------
acts_like? 85.372k i/100ms
fast_acts_like? 166.097k i/100ms
Calculating -------------------------------------
acts_like? 1.720M (± 8.3%) i/s - 8.537M in 5.001003s
fast_acts_like? 4.695M (±10.1%) i/s - 23.254M in 5.010734s
Comparison:
fast_acts_like?: 4695493.1 i/s
acts_like?: 1719637.9 i/s - 2.73x slower
==================================== string ====================================
================================= Memory Usage =================================
value.acts_like?
{:FREE=>-2001, :T_STRING=>2000}
value.fast_acts_like?
{:FREE=>-1}
================================ Benchmark.ips =================================
Warming up --------------------------------------
acts_like? 100.221k i/100ms
fast_acts_like? 182.841k i/100ms
Calculating -------------------------------------
acts_like? 1.706M (± 7.3%) i/s - 8.519M in 5.022331s
fast_acts_like? 3.968M (±22.8%) i/s - 18.650M in 5.006762s
Comparison:
fast_acts_like?: 3967972.9 i/s
acts_like?: 1705773.7 i/s - 2.33x slower
================================= super_hacka ==================================
================================= Memory Usage =================================
value.acts_like?
{:FREE=>-2004, :T_STRING=>2002, :T_SYMBOL=>1}
value.fast_acts_like?
{:FREE=>-2003, :T_STRING=>2001, :T_SYMBOL=>1}
================================ Benchmark.ips =================================
Warming up --------------------------------------
acts_like? 100.344k i/100ms
fast_acts_like? 101.690k i/100ms
Calculating -------------------------------------
acts_like? 1.617M (± 7.5%) i/s - 8.128M in 5.055285s
fast_acts_like? 1.534M (±10.1%) i/s - 7.627M in 5.031052s
Comparison:
acts_like?: 1617390.7 i/s
fast_acts_like?: 1533897.3 i/s - same-ish: difference falls within error
Diffstat (limited to 'actionpack/test/dispatch/runner_test.rb')
0 files changed, 0 insertions, 0 deletions