[Cuis-dev] Problems in class Number

Andres Valloud ten at smallinteger.com
Fri Oct 11 20:02:49 PDT 2019


I think this happened because we are measuring against different number 
sets so we ended up tuning to our tests.  By the way, I'm having some 
trouble getting reliable times, the figures seem to change by ~10% 
without any obvious reason.  For instance, for the last code you sent, 
running that through some of the tests here results in times ranging 
from 2272 to 2510 milliseconds --- and that's starting from a clean 
system after a GC, so each run starts in the same conditions.  That's a 
lot of difference for a computer that should be roughly stable...

Would you mind checking the numbers you get with the attached method? 
It just takes your latest code and increases the boundary for the small 
number loop to 8281.  Here's why I'd like to see what happens for you:

"your latest"
Time millisecondsToRun: [10000 timesRepeat: [1 to: 8281 by: 8 do: [:x | 
x isPrimeFast1c]]] 1647

"attached here"
Time millisecondsToRun: [10000 timesRepeat: [1 to: 8281 by: 8 do: [:x | 
x isPrimeFast1d]]] 1565

Andres.

On 10/11/19 10:59, Agustín Sansone via Cuis-dev wrote:
> Latest code you sent:
> Time millisecondsToRun:
>         [1 to: 10000000 do: [:e | e isPrimeFast]].  16025
> 
> Latest code I sent:
> Time millisecondsToRun:
>         [1 to: 10000000 do: [:e | e isPrimeFast]].  14435
> 
> 
> El vie., 11 oct. 2019 a las 2:09, Andres Valloud via Cuis-dev 
> (<cuis-dev at lists.cuis.st <mailto:cuis-dev at lists.cuis.st>>) escribió:
> 
>     Euclid's gcd algorithm converges to the answer exponentially with base
>     phi.  Larger small integers help amortize the extra cost.
> 
>     On 10/10/19 21:53, Phil B wrote:
>      > Was that primarily due to the 64-bit version mostly fitting within
>      > SmallInteger?  I find many numeric performance issues just melt
>     away by
>      > staying away from Large*Integer (and Fraction)... they're great for
>      > maintaining accuracy, lousy for performance.  As in multiples to
>     orders
>      > of magnitude worse depending on what you're doing.
>      >
>      > On Fri, Oct 11, 2019 at 12:40 AM Andres Valloud via Cuis-dev
>      > <cuis-dev at lists.cuis.st <mailto:cuis-dev at lists.cuis.st>
>     <mailto:cuis-dev at lists.cuis.st <mailto:cuis-dev at lists.cuis.st>>> wrote:
>      >
>      >     Fascinating --- the gcd approach was pretty bad in 32 bit land.
>      >     However, in 64 bits, the gcd batches are large enough to
>     amortize the
>      >     cost, and that detects most composites without sending
>     sqrtFloor.  The
>      >     small integer threshold is now 91 squared.
>      >
>      >     On 10/10/19 20:37, Agustín Sansone via Cuis-dev wrote:
>      >      >     Well, what do you think?  Are we done going over this poor
>      >     method?
>      >      >
>      >      >
>      >      > Okay, I'm happy with this version.
>      >      >
>      >     --
>      >     Cuis-dev mailing list
>      > Cuis-dev at lists.cuis.st <mailto:Cuis-dev at lists.cuis.st>
>     <mailto:Cuis-dev at lists.cuis.st <mailto:Cuis-dev at lists.cuis.st>>
>      > https://lists.cuis.st/mailman/listinfo/cuis-dev
>      >
>     -- 
>     Cuis-dev mailing list
>     Cuis-dev at lists.cuis.st <mailto:Cuis-dev at lists.cuis.st>
>     https://lists.cuis.st/mailman/listinfo/cuis-dev
> 
> 
-------------- next part --------------
'From Cuis 5.0 [latest update: #3866] on 11 October 2019 at 7:56:35 pm'!

!Integer methodsFor: 'testing' stamp: 'sqr 10/11/2019 19:55:13'!
isPrimeFast1d

	self < 3 ifTrue: [^self = 2].
	self even ifTrue: [^false].
	self \\ 3 = 0 ifTrue: [^self = 3].
	self \\ 5 = 0 ifTrue: [^self = 5].
	self < 8281 ifTrue: [
		"Approximate sqrtFloor to avoid computational expense"
		self \\ 7 = 0 ifTrue: [^self = 7].
		self \\ 11 = 0 ifTrue: [^self  = 11].
		self \\ 13 = 0 ifTrue: [^self  = 13].
		12 to: (self bitShift: -6) + 11 by: 6 do:
			[:each | self \\ (each+5) = 0 ifTrue: [ ^false ].
					self \\ (each+7) = 0 ifTrue: [ ^false ]].
		^true
	].
	"Now 2, 3 and 5 do not divide self. So, self is of the form
	 30*k + {1, 7, 11, 13, 17, 19, 23, 29} for integer k >= 0.
	The 31 case below is the 30k+1 case, excluding k = 0"
	0 to: self sqrtFloor by: 30 do: [:each |
		self \\ (each+7) = 0 ifTrue: [ ^false ].
		self \\ (each+11) = 0 ifTrue: [ ^false ].
		self \\ (each+13) = 0 ifTrue: [ ^false ].
		self \\ (each+17) = 0 ifTrue: [ ^false ].
		self \\ (each+19) = 0 ifTrue: [ ^false ].
		self \\ (each+23) = 0 ifTrue: [ ^false ].
		self \\ (each+29) = 0 ifTrue: [ ^false ].
		self \\ (each+31) = 0 ifTrue: [ ^false ].
	].
	^true
! !


More information about the Cuis-dev mailing list