aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
authoryui-knk <spiketeika@gmail.com>2016-05-01 23:54:03 +0900
committerJeremy Daer <jeremydaer@gmail.com>2016-05-07 21:57:00 -0700
commit0c34773bf57916e64f0fb15577891a6e5c5171c6 (patch)
treee8ba6b9dd4012a28399b3dc38ef262cc0e5d4cd1 /activesupport
parent332f9d1afdcf164b1c1453c727c42dc010f80e5b (diff)
downloadrails-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.rb12
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