> On 01 Dec 2015, at 10:18, Ben Coman <b...@openinworld.com> wrote:
> 
> On Tue, Dec 1, 2015 at 4:45 PM, Sven Van Caekenberghe <s...@stfx.eu> wrote:
>> I am all for a cleanup, the current situation is confusing.
>> The basic #sum should be fast AND work for empty collections with 0 as 
>> starting element.
> 
>> I know why the #anyOne is used, and that use case should be preserved, but 
>> it is less common IMHO.
> 
> I'm curious to be learn why?

How many times have you summed a collection of things, where (1) you could not 
start from the number 0 and (2) the operation was #+ ? Me, never, and if I 
would need that, I would do an #inject:into: myself. Any counter examples that 
occur a lot ?

> cheers -ben
> 
>> 
>>> On 01 Dec 2015, at 09:38, Thierry Goubier <thierry.goub...@gmail.com> wrote:
>>> 
>>> Hi Max,
>>> 
>>> Interesting results...
>>> 
>>> replacing the #yourself in newSum: cuts the runtime by a factor of two.
>>> using an [:x | x ] block cost 10% compared to a direct version of sum.
>>> 
>>> So the fastest sum is:
>>> 
>>> sum
>>>      ^ self
>>>              inject:
>>>                      (self ifEmpty: [ ^ 0 ] ifNotEmpty: [ self anyOne ])
>>>              into: [ :sum :each | sum + each ]
>>> 
>>> And
>>> 
>>> sum
>>>    ^ self sum: [:x | x ]
>>> 
>>> is 10% slower.
>>> 
>>> And
>>> 
>>> sum
>>>    ^ self sum: #yourself
>>> 
>>> is 100% slower (i.e. x2)
>>> 
>>> It may be wise to avoid using #yourself for a block.
>>> 
>>> Thierry
>>> 
>>> 
>>> 2015-12-01 9:17 GMT+01:00 Max Leske <maxle...@gmail.com>:
>>> 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
>>> 
>> 
>> 
> 


Reply via email to