Optimizations and tweaks (was Re: [q-lang-users] Problem using function "isprime")
Brought to you by:
agraef
From: Tim H. <q...@st...> - 2004-10-09 22:39:31
|
Dr....@t-... (Albert Graef) writes: [snip] >> Not quite as pretty to look at, but I think it may run faster as it only >> uses the primes between 2..intsqrt N rather than all odds, if I read your >> algorithm right... > > Hi, Tim! From the algorithm I posted: > > > =3D try_div 3 (intsqrt N) N otherwise; > ^^^^^^^ > > See? :) Yes... I had that too... > While your algorithm looks quite neat, I doubt that it will be any > faster, since it uses a list, while the one from the docs is just plain > tail-recursive number crunching (which has the added benefit that it only > needs O(1) space). I'm also a bit worried about the recursive isprime > call, which might slow down things quite a bit if enough members of the > [2..N] list fail the Miller-Rabin test. Very interesting concerns, but I've just been very rude and benchmarked the two... :) For smallish N<1E4, it's evenly matched (3% more occasions on which mine is faster than yours).=20 However, for N approaching 1E9 or so, the number of occasions on which my algorithm is faster pulls away - around 2.1E9 I've been seeing about 3x as many occasions on which mine's been faster compared to yours. It seems to be taking 2-3% less time, when it's better. The recursive isprime call is actually a win; effectively it's calling intsqrt(intsqrt(intsqrt(intsqrt.....))) a few times (per prime in range, not per-odd-number in range) which tends towards 1 quicker than your concern about implementation slows it down. Bear in mind that only 1/12 numbers in the range [1..1E6] is a prime, too... It can of course be considerably quicker: just by amending=20 primes N =3D [2] if N=3D2;=20=20=20=20=20=20=20=20=20 =3D [2,3] if N=3D3; //cheating! =3D filter isprime [2..N] otherwise; it's faster than yours on 10x as many ocassasion than where yours was faster than mine, around N<=3D2E9, so it's hitting the bottom few cases of the recursion quite a *lot*. ~~~~ What I'd like to know is whether there's any memoization going on - by the time I've evaluated `isprime 13' once for intsqrt(N), I don't need to do it all over again for intsqrt(intsqrt(N)), etc. Actually, how would I write a memoize function in Q, anyway? I don't see that, or the word `cache', in the docs anywhere :) ~Tim =2D-=20 <http://spodzone.org.uk/> |