diff options
author | yui-knk <spiketeika@gmail.com> | 2016-05-01 23:54:03 +0900 |
---|---|---|
committer | Jeremy Daer <jeremydaer@gmail.com> | 2016-05-07 21:57:00 -0700 |
commit | 0c34773bf57916e64f0fb15577891a6e5c5171c6 (patch) | |
tree | e8ba6b9dd4012a28399b3dc38ef262cc0e5d4cd1 /activesupport | |
parent | 332f9d1afdcf164b1c1453c727c42dc010f80e5b (diff) | |
download | rails-0c34773bf57916e64f0fb15577891a6e5c5171c6.tar.gz rails-0c34773bf57916e64f0fb15577891a6e5c5171c6.tar.bz2 rails-0c34773bf57916e64f0fb15577891a6e5c5171c6.zip |
Use original `Array#sum` to speed up calculating
Use original `Array#sum` when calculating Numeric sum.
This commit is related #24804 issue.
Issue #24804 reports `Array#sum` becomes much slower when
ActiveSupport is included.
This commit tries to use original method as far as possible.
```shell
$ cat array_sum.rb
class Array
alias core_sum sum
end
require 'benchmark/ips'
require 'active_support/core_ext/enumerable'
ary = [1.0] * 1_000_000
Benchmark.ips do |x|
x.report("core sum") { ary.core_sum }
x.report("AS's sum") { ary.sum }
x.compare!
end
$ bundle exec ruby -v -I lib array_sum.rb
ruby 2.4.0dev (2016-05-01 master 54867) [x86_64-darwin14]
Calculating -------------------------------------
core sum 4.000 i/100ms
AS's sum 5.000 i/100ms
-------------------------------------------------
core sum 50.492 (± 7.9%) i/s - 252.000
AS's sum 50.116 (± 6.0%) i/s - 250.000
Comparison:
core sum: 50.5 i/s
AS's sum: 50.1 i/s - 1.01x slower
```
Signed-off-by: Jeremy Daer <jeremydaer@gmail.com>
Diffstat (limited to 'activesupport')
-rw-r--r-- | activesupport/lib/active_support/core_ext/enumerable.rb | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb index eae964bc2e..9a893157ea 100644 --- a/activesupport/lib/active_support/core_ext/enumerable.rb +++ b/activesupport/lib/active_support/core_ext/enumerable.rb @@ -114,11 +114,15 @@ end # just calling the compat method in the first place. if Array.instance_methods(false).include?(:sum) && !(%w[a].sum rescue false) class Array - remove_method :sum + alias :orig_sum :sum - def sum(*args) #:nodoc: - # Use Enumerable#sum instead. - super + def sum(init = nil, &block) #:nodoc: + if init.is_a?(Numeric) || first.is_a?(Numeric) + init ||= 0 + orig_sum(init, &block) + else + super + end end end end |