-
Ricardo Díaz authored
Commit: https://github.com/ruby/ruby/commit/9ca738927293df1c7a2a1ed7e2d6cf89527b5438 Discussion: https://bugs.ruby-lang.org/issues/14473 It seems to be compatible with the original ActiveSupport's implementation, at least based on the test suite. It also works faster: ``` Warming up -------------------------------------- Ruby's Range#cover? 1.196M i/100ms ActiveSupport's Range#cover? 396.369k i/100ms Calculating ------------------------------------- Ruby's Range#cover? 11.889M (± 1.7%) i/s - 59.820M in 5.033066s ActiveSupport's Range#cover? 3.951M (± 1.2%) i/s - 19.818M in 5.017176s Comparison: Ruby's Range#cover?: 11888979.3 i/s ActiveSupport's Range#cover?: 3950671.0 i/s - 3.01x (± 0.00) slower ``` Benchmark script: ```ruby require "minitest/autorun" require "benchmark/ips" module ActiveSupportRange def active_support_cover?(value) if value.is_a?(::Range) is_backwards_op = value.exclude_end? ? :>= : :> return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end) # 1...10 covers 1..9 but it does not cover 1..10. # 1..10 covers 1...11 but it does not cover 1...12. operator = exclude_end? && !value.exclude_end? ? :< : :<= value_max = !exclude_end? && value.exclude_end? ? value.max : value.last cover?(value.first) && (self.end.nil? || value_max.public_send(operator, last)) else cover? end end end class BugTest < Minitest::Test def test_range_cover Range.prepend(ActiveSupportRange) range = (1..10000) Benchmark.ips do |x| x.report("Ruby's Range#cover?") do range.cover?((100..20)) end x.report("ActiveSupport's Range#cover?") do range.active_support_cover?((100..20)) end x.compare! end end end ```
Ricardo Díaz authoredCommit: https://github.com/ruby/ruby/commit/9ca738927293df1c7a2a1ed7e2d6cf89527b5438 Discussion: https://bugs.ruby-lang.org/issues/14473 It seems to be compatible with the original ActiveSupport's implementation, at least based on the test suite. It also works faster: ``` Warming up -------------------------------------- Ruby's Range#cover? 1.196M i/100ms ActiveSupport's Range#cover? 396.369k i/100ms Calculating ------------------------------------- Ruby's Range#cover? 11.889M (± 1.7%) i/s - 59.820M in 5.033066s ActiveSupport's Range#cover? 3.951M (± 1.2%) i/s - 19.818M in 5.017176s Comparison: Ruby's Range#cover?: 11888979.3 i/s ActiveSupport's Range#cover?: 3950671.0 i/s - 3.01x (± 0.00) slower ``` Benchmark script: ```ruby require "minitest/autorun" require "benchmark/ips" module ActiveSupportRange def active_support_cover?(value) if value.is_a?(::Range) is_backwards_op = value.exclude_end? ? :>= : :> return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end) # 1...10 covers 1..9 but it does not cover 1..10. # 1..10 covers 1...11 but it does not cover 1...12. operator = exclude_end? && !value.exclude_end? ? :< : :<= value_max = !exclude_end? && value.exclude_end? ? value.max : value.last cover?(value.first) && (self.end.nil? || value_max.public_send(operator, last)) else cover? end end end class BugTest < Minitest::Test def test_range_cover Range.prepend(ActiveSupportRange) range = (1..10000) Benchmark.ips do |x| x.report("Ruby's Range#cover?") do range.cover?((100..20)) end x.report("ActiveSupport's Range#cover?") do range.active_support_cover?((100..20)) end x.compare! end end end ```
Loading