And they chose one that wasnât too optimized. There are much better versions of factorial already implemented in Smalltalk: https://medium.com/concerning-pharo/speeding-up-factorial-computation-by-cha... http://forum.world.st/Challenge-Tuning-the-large-factorial-td3588660.html Both of these pages have optimizations that eliminate 80% or more of the running time where the optimized version below only eliminates ~25% of the slow factorialâs running time. On my machine, running the factorial for 200,000 takes ~20 seconds using the old/slow algorithm (once I fixed it to be recursive on itself and not the modified factorial method), and the new factorial method takes ~15 seconds. Using the #productTo: method above, takes ~4 seconds, and using my revised version on the other page above takes ~3.5 seconds. My personal preference for a factorial included with Pharo would be the #productTo: method above. It is simple to understand and is reasonably fast. John Brant
On May 16, 2020, at 11:17 AM, Bernhard Höfner <bernhard.hoefner@gmx.de> wrote:
It seems that someone needed an optimized factorial-routine⦠The problem on the other hand is, that the machine friendly code is much less âdidactical" than the human friendly common implementation. To have both I propose to add the human friendly clear and short version as comment. Its a bit like some primitive methods were after the primitive call there is the smalltalk version as well (VisualWorks).
Regards, Bernhard Höfner
... The algos are different:
Pharo 8: Integer>>factorial "Answer the factorial of the receiver."
self = 0 ifTrue: [^ 1]. self > 0 ifTrue: [^ self * (self - 1) factorial]. self error: 'Not valid for negative integers'
Pharo 9:
Integer>>factorial | nex nexnext acc | "Guard for know cases (0,1,2,error)" self < 3 ifTrue: [ ^ self < 0 ifTrue: [ self error: 'Not valid for negative integers' ] ifFalse: [ self > 0 ifTrue: [ self ] ifFalse: [ 1 ] ] ]. acc := 2. nex := 2. nexnext := 10.
self // 2 - 1 timesRepeat: [ nex := nex + nexnext. nexnext := nexnext + 8. acc := acc * nex ]. self odd ifTrue: [ acc := acc * self ]. ^ acc
...