Skip to content

Commit

Permalink
Merge pull request #2359 from herwinw/range_sum
Browse files Browse the repository at this point in the history
Optimize Enumerable#sum for integer ranges
  • Loading branch information
herwinw committed Nov 26, 2024
2 parents 7383ed0 + 0367e82 commit 93e4dff
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/enumerable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,10 @@ def sort_by(&block)

def sum(init = 0)
block_given = block_given?
if !block_given && init == 0 && is_a?(Range) && first.is_a?(Integer) && self.last.is_a?(Integer)
last = exclude_end? ? self.last - 1 : self.last
return (first + last) * (last - first + 1) / 2
end
each do |item|
if block_given
init += yield item
Expand Down
13 changes: 13 additions & 0 deletions test/natalie/enumerable_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,17 @@ def each
-> { [1].zip [], Object.new, [] }.should raise_error(TypeError)
end
end

describe '#sum' do
it 'should return the correct result with optimized Range operations' do
(1..1000).sum.should == 500500
(1...1000).sum.should == 499500
(10..20).sum.should == 165
end

it 'falls back to the default implementation when range is not numeric or a start is given' do
('a'..'c').sum('').should == 'abc'
(1..3).sum(10).should == 16
end
end
end

0 comments on commit 93e4dff

Please sign in to comment.