mirror of https://github.com/rails/rails
7cfc4ee676
By using `ruby2_keyword` style delegation we we can avoid a few allocations and some extra checks. ``` $ ruby --yjit /tmp/bench-as-time-at.rb ruby 3.2.2 (2023-03-30 revision e51014f9c0) +YJIT [arm64-darwin22] === Complex call ==== Warming up -------------------------------------- Time.without 320.514k i/100ms Time.with 68.433k i/100ms Time.opt_with 167.532k i/100ms Calculating ------------------------------------- Time.without 3.781M (± 4.8%) i/s - 18.910M in 5.014574s Time.with 1.586M (± 3.5%) i/s - 7.938M in 5.010525s Time.opt_with 2.003M (± 2.4%) i/s - 10.052M in 5.021309s Comparison: Time.without: 3781330.9 i/s Time.opt_with: 2003025.9 i/s - 1.89x slower Time.with: 1586289.9 i/s - 2.38x slower Time.without: 2.003 alloc/iter Time.with: 9.002 alloc/iter Time.opt_with: 7.002 alloc/iter === Simple call ==== Warming up -------------------------------------- Time.without 749.097k i/100ms Time.with 342.855k i/100ms Time.opt_with 416.063k i/100ms Calculating ------------------------------------- Time.without 9.289M (± 3.4%) i/s - 46.444M in 5.005361s Time.with 3.601M (± 2.1%) i/s - 18.171M in 5.048794s Time.opt_with 4.373M (± 8.1%) i/s - 22.051M in 5.084967s Comparison: Time.without: 9289271.2 i/s Time.opt_with: 4373226.2 i/s - 2.12x slower Time.with: 3600733.6 i/s - 2.58x slower Time.without: 1.002 alloc/iter Time.with: 3.001 alloc/iter Time.opt_with: 3.002 alloc/iter ``` ```ruby require 'bundler/inline' gemfile do source 'https://rubygems.org' gem 'activesupport', require: 'active_support/all', github: 'rails/rails' gem 'benchmark-ips' end class Time class << self def opt_at_with_coercion(time_or_number, *args) if args.empty? if time_or_number.is_a?(ActiveSupport::TimeWithZone) at_without_coercion(time_or_number.to_r).getlocal elsif time_or_number.is_a?(DateTime) at_without_coercion(time_or_number.to_f).getlocal else at_without_coercion(time_or_number) end else at_without_coercion(time_or_number, *args) end end ruby2_keywords :opt_at_with_coercion end end puts RUBY_DESCRIPTION puts "=== Complex call ====" Benchmark.ips do |x| x.report("Time.without") do ::Time.at_without_coercion(223423423, 32423423, :nanosecond, in: "UTC") end x.report("Time.with") do ::Time.at_with_coercion(223423423, 32423423, :nanosecond, in: "UTC") end x.report("Time.opt_with") do ::Time.opt_at_with_coercion(223423423, 32423423, :nanosecond, in: "UTC") end x.compare!(order: :baseline) end def measure_allocs(title, iterations: 1_000) before = GC.stat(:total_allocated_objects) iterations.times do yield end allocs = GC.stat(:total_allocated_objects) - before puts "#{title}: #{allocs.to_f / iterations} alloc/iter" end measure_allocs("Time.without") do ::Time.at_without_coercion(223423423, 32423423, :nanosecond, in: "UTC") end measure_allocs("Time.with") do ::Time.at_with_coercion(223423423, 32423423, :nanosecond, in: "UTC") end measure_allocs("Time.opt_with") do ::Time.opt_at_with_coercion(223423423, 32423423, :nanosecond, in: "UTC") end puts "=== Simple call ====" Benchmark.ips do |x| x.report("Time.without") do ::Time.at_without_coercion(223423423) end x.report("Time.with") do ::Time.at_with_coercion(223423423) end x.report("Time.opt_with") do ::Time.opt_at_with_coercion(223423423) end x.compare!(order: :baseline) end def measure_allocs(title, iterations: 1_000) before = GC.stat(:total_allocated_objects) iterations.times do yield end allocs = GC.stat(:total_allocated_objects) - before puts "#{title}: #{allocs.to_f / iterations} alloc/iter" end measure_allocs("Time.without") do ::Time.at_without_coercion(223423423) end measure_allocs("Time.with") do ::Time.at_with_coercion(223423423) end measure_allocs("Time.opt_with") do ::Time.opt_at_with_coercion(223423423, 32423423) end ``` |
||
---|---|---|
.. | ||
bin | ||
lib | ||
test | ||
.gitignore | ||
CHANGELOG.md | ||
MIT-LICENSE | ||
README.rdoc | ||
Rakefile | ||
activesupport.gemspec |
README.rdoc
= Active Support -- Utility classes and Ruby extensions from \Rails Active Support is a collection of utility classes and standard library extensions that were found useful for the \Rails framework. These additions reside in this package so they can be loaded as needed in Ruby projects outside of \Rails. You can read more about the extensions in the {Active Support Core Extensions}[https://guides.rubyonrails.org/active_support_core_extensions.html] guide. == Download and installation The latest version of Active Support can be installed with RubyGems: $ gem install activesupport Source code can be downloaded as part of the \Rails project on GitHub: * https://github.com/rails/rails/tree/main/activesupport == License Active Support is released under the MIT license: * https://opensource.org/licenses/MIT == Support API documentation is at: * https://api.rubyonrails.org Bug reports for the Ruby on \Rails project can be filed here: * https://github.com/rails/rails/issues Feature requests should be discussed on the rails-core mailing list here: * https://discuss.rubyonrails.org/c/rubyonrails-core