rails/activesupport
Jean Boussier d36eb23976 Specialize various #present? implementations
Because `#present?` always resolve to `Object#present?`, it's
an extremely polymorphic method, and inline cache hits are low.

In addition, it requires an extra call to `self.blank?` which is
an overhead.

By specializing `present?` on common types, we avoid both of these
slow-downs:

```

ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin22]
Warming up --------------------------------------
            present?   198.028k i/100ms
        opt_present?   565.521k i/100ms
Calculating -------------------------------------
            present?      2.087M (± 8.8%) i/s -     10.297M in   5.028398s
        opt_present?      5.584M (± 8.6%) i/s -     27.711M in   5.023852s

Comparison:
            present?:  2086621.6 i/s
        opt_present?:  5584373.5 i/s - 2.68x  faster
```

```
ruby 3.2.2 (2023-03-30 revision e51014f9c0) +YJIT [arm64-darwin22]
Warming up --------------------------------------
            present?   819.792k i/100ms
        opt_present?     1.047M i/100ms
Calculating -------------------------------------
            present?     12.192M (± 8.8%) i/s -     60.665M in   5.050622s
        opt_present?     16.540M (± 8.2%) i/s -     82.676M in   5.059029s

Comparison:
            present?: 12192047.5 i/s
        opt_present?: 16539689.6 i/s - 1.36x  faster
```

```ruby

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'benchmark-ips'
  gem 'activesupport'
end

require 'active_support/all'

class Object
  def opt_present?
    respond_to?(:empty?) ? !empty? : !!self
  end
end

class NilClass
  def opt_present?
    false
  end
end

class FalseClass
  def opt_present?
    false
  end
end

class TrueClass
  def opt_present?
    true
  end
end

class Array
  def opt_present?
    !empty?
  end
end

class Hash
  def opt_present?
    !empty?
  end
end

class Symbol
  def opt_present?
    !empty?
  end
end

class String
  def opt_present?
    !blank?
  end
end

class Numeric # :nodoc:
  def opt_present?
    true
  end
end

class Time # :nodoc:
  def opt_present?
    true
  end
end

array = []
hash = {}
time = Time.now

puts RUBY_DESCRIPTION
Benchmark.ips do |x|
  x.report("present?") do
    true.present?
    false.present?
    1.present?
    1.0.present?
    array.present?
    hash.present?
    :foo.present?
    time.present?
  end

  x.report("opt_present?") do
    true.opt_present?
    false.opt_present?
    1.opt_present?
    1.0.opt_present?
    array.opt_present?
    hash.opt_present?
    :foo.opt_present?
    time.opt_present?
  end

  x.compare!(order: :baseline)
end
```
2023-11-04 08:45:51 +01:00
..
bin Remove AS::Multibyte's unicode table 2018-02-20 03:58:22 +09:00
lib Specialize various #present? implementations 2023-11-04 08:45:51 +01:00
test Merge pull request #49669 from intrip/fix-message-metadata-non-str 2023-11-01 11:22:36 +01:00
.gitignore Clean up and consolidate .gitignores 2018-02-17 14:26:19 -08:00
activesupport.gemspec Drop dependency on mutex_m 2023-10-18 14:27:26 +02:00
CHANGELOG.md Improve error messages of assert_changes and assert_no_changes 2023-10-30 13:30:33 -05:00
MIT-LICENSE Remove Copyright years (#47467) 2023-02-23 11:38:16 +01:00
Rakefile Stop testing hiredis 2022-08-22 09:01:27 +02:00
README.rdoc 🔗 Remove RDoc auto-link from Rails module everywhere 2023-06-23 10:49:30 +09:00

= 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