Skip to content

Commit

Permalink
Optimize Range#sum to use arithmetic progression when a block is not …
Browse files Browse the repository at this point in the history
…given [#2489].

Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
  • Loading branch information
josevalim authored and lifo committed Aug 9, 2009
1 parent d811864 commit 1bd4d1c
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 0 deletions.
9 changes: 9 additions & 0 deletions activesupport/lib/active_support/core_ext/enumerable.rb
Expand Up @@ -111,3 +111,12 @@ def none?(&block)
!any?(&block)
end unless [].respond_to?(:none?)
end

class Range #:nodoc:
# Optimize range sum to use arithmetic progression if a block is not given.
def sum(identity=0, &block)
return super if block_given?
actual_last = exclude_end? ? (last - 1) : last
(actual_last - first + 1) * (actual_last + first) / 2
end
end
2 changes: 2 additions & 0 deletions activesupport/test/core_ext/enumerable_test.rb
Expand Up @@ -61,7 +61,9 @@ def test_empty_sums
end

def test_enumerable_sums
assert_equal 20, (1..4).sum { |i| i * 2 }
assert_equal 10, (1..4).sum
assert_equal 6, (1...4).sum
end

def test_each_with_object
Expand Down

3 comments on commit 1bd4d1c

@marcandre
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should not assume that a Range is a range of fixnums!

For example:
('a'..'c').sum now fails

You should return super if block_given? || !(first.instance_of?(Fixnum) || last.instance_of?(Fixnum))

@joshuaclayton
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marc-Andre,

It could be argued that you should know not to call sum on a range of characters, much like how you wouldn't call upcase or strip on a fixnum. However, I think it makes more sense to concatenate the characters together, much like what Array#sum does => ("a".."c").map.sum == "abc"

@josevalim
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to ask why someone would sum something which is not numbers, but @joshuaclayton gave a good example. :)
Already provided a patch, thanks guys.

Please sign in to comment.