The differences between #sum: and #sumNumbers: are well described in
the respective method comments, but I agree that this may be a problem
as most people will go for #sum: even for basic numeric collections.
(And I personally got bit by this.)

So maybe #sum: could adopt #sumNumbers: implementation, and the current
#sum: implementation would be moved to #domainSum: (or some other
appropriate name...)?

As for #detectSum: I think this method has confusing name and is
functionally duplicate to #sum:.

The swapped arguments there may make sense when you overload #+, however
the same thing can be achieved from the provided block ...


On 12/01, Max Leske wrote:
> Hi guys,
> 
> Collection defines #sum:, #detectSum: and #sumNumbers:, all of which 
> accomplish the same (in principal) but with subtle differences:
> 
> #sum:
> - uses #inject:into: with #anyOne as the injected element and will thus fail 
> for empty collections
> 
> #detectSum:
> - uses “nextValue + sum” instead of “sum + nextValue” which makes it a lot 
> slower when dealing with large numbers (primitive fails and number conversion 
> is necessary)
> 
> #sumNumbers:
> - same as #sum but doesn’t fail for empty collections. Only good for numbers 
> though.
> 
> 
> Benchmarks:
> 
> [ 100 timesRepeat: [ (1 to: 1000000) sum: #yourself ] ] timeToRun 18062
> [ 100 timesRepeat: [ (1 to: 1000000) detectSum: #yourself ] ] timeToRun 42391
> [ 100 timesRepeat: [ (1 to: 1000000) sumNumbers: #yourself ] ] timeToRun 18096
> 
> 
> 
> Can we settle for a single implementation? Such as (modified from 
> #sumNumbers:):
> 
> newSum: aBlock
>       ^ self 
>               inject: (self
>                       ifEmpty: [ 0 ]
>                       ifNotEmpty: [ self anyOne ]) 
>               into: [ :sum :each |  sum + (aBlock value: each) ]
> 
> This implementation combines the best of the three implementations I think. 
> Benchmark:
> 
> [ 100 timesRepeat: [ (1 to: 1000000) newSum: #yourself ] ] timeToRun 17955
> 
> 
> BTW, there is also the message #sum, which suffers from the same problem as 
> #sum: (the implementation is basically a copy). #sum could be implemented as
> 
> sum
>       ^ self sum: [ :x | x ]
> 
> 
> As for the name for the new method, I suggest #sum:.
> 
> Cheers,
> Max

-- 
Peter

Reply via email to