From 0c34773bf57916e64f0fb15577891a6e5c5171c6 Mon Sep 17 00:00:00 2001
From: yui-knk <spiketeika@gmail.com>
Date: Sun, 1 May 2016 23:54:03 +0900
Subject: Use original `Array#sum` to speed up calculating
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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>
---
 activesupport/lib/active_support/core_ext/enumerable.rb | 12 ++++++++----
 1 file 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
-- 
cgit v1.2.3