## Why is sum so much faster than inject(:+)?

Question

So I was running some benchmarks in Ruby 2.4.0 and realized that

```
(1...1000000000000000000000000000000).sum
```

calculates immediately whereas

```
(1...1000000000000000000000000000000).inject(:+)
```

takes so long that I just aborted the operation. I was under the impression that `Range#sum`

was an alias for `Range#inject(:+)`

but it seems like that is not true. So how does `sum`

work, and why is it so much faster than `inject(:+)`

?

**N.B.** The documentation for `Enumerable#sum`

(which is implemented by `Range`

) does not say anything about lazy evaluation or anything along those lines.

Show source

## Answers to Why is sum so much faster than inject(:+)? ( 1 )

## Short answer

For an integer range :

`Enumerable#sum`

returns`(range.max-range.min+1)*(range.max+range.min)/2`

`Enumerable#inject(:+)`

iterates over every element.## Theory

The sum of integers between 1 and

`n`

is called a triangular number, and is equal to`n*(n+1)/2`

.The sum of integers between

`n`

and`m`

is the triangular number of`m`

minus the triangular number of`n-1`

, which is equal to`m*(m+1)/2-n*(n-1)/2`

, and can be written`(m-n+1)*(m+n)/2`

.## Enumerable#sum in Ruby 2.4

This property in used in

`Enumerable#sum`

for integer ranges :`int_range_sum`

looks like this :which is equivalent to:

the aforementioned equality!

## Complexity

Thanks a lot to @k_g and @Hynek-Pichi-Vychodil for this part!

## sum

`(1...1000000000000000000000000000000).sum`

requires three additions, a multiplication, a substraction and a division.It's a constant number of operations, but multiplication is O((log n)²), so

`Enumerable#sum`

is O((log n)²) for an integer range.## inject

`(1...1000000000000000000000000000000).inject(:+)`

requires 999999999999999999999999999998 additions!

Addition is O(log n), so

`Enumerable#inject`

is O(n log n).With

`1E30`

as input,`inject`

with never return. The sun will explode long before!## Test

It's easy to check if Ruby Integers are being added :

Indeed, from

`enum.c`

comments :