Hmm. On Tue, Dec 1, 2015 at 12:17 AM, Max Leske <[email protected]> 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) > > Interesting. On my machine (which is apparently really slow right now), I get: [ 100 timesRepeat: [ (1 to: 1000000) detectSum: [:x|x] ] ] timeToRun 104874 [ 100 timesRepeat: [ (1 to: 1000000) detectSumSwitch: [:x|x] ] ] timeToRun 44369 (this second one is where I add have switched the order - sum + nextValue - for speed. So, a little over twice as fast). If I change SmallInteger to be a bit smarter, I get: [ 100 timesRepeat: [ (1 to: 1000000) detectSum: [:x|x] ] ] timeToRun 45257 In other words just marginally slower than the optimized method above. The benefit here is that future folks won't have to remember which way to do their arithmetic to make things fast. Smarter + (in SmallInteger): + aNumber "Primitive. Add the receiver to the argument and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger Essential No Lookup. See Object documentation whatIsAPrimitive." <primitive: 1> ^aNumber class = SmallInteger ifFalse: [aNumber + self] ifTrue: [super + aNumber] Of course, this wants to be thoroughly tested before use - certain additions may now work in ways not expected before (such as adding an array to a small integer - you may get odd results). Still... > #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 > > > <snip> -cbc
