[Tutor] Help Optimise Code
Lie Ryan
lie.1296 at gmail.com
Wed Nov 19 22:26:55 CET 2008
On Wed, 19 Nov 2008 13:13:18 +0000, Richard Lovely wrote:
> I'm pretty new to code optimisation, so I thought I'd ask you all for
> advice.
>
> I'm making an iterative prime number generator. This is what I've got so
> far:
>
> Code: Select all
> import math, array
>
> def count2(start_at=0):
> 'Yield every third integer, beginning with start_at'
> # this has been
> tested as faster than using itertools.count
> while True:
> yield start_at
> start_at += 2
>
> def iprimes():
> 'generate an endless sequence of prime numbers'
> yield 2
> yield 3
> yield 5
> sqrt = math.sqrt
> # 'L' for unsigned long - not tested if
> # using a smaller type is faster
> knownPrimes = array.array("L",(3,5))
> for x in count2(7):
> # take extra function calls out of the inner loop
> sqrtX = sqrt(x)
> for p in knownPrimes:
> test = (not x % p) and -1 or p > sqrtX
> if test == -1: # (not > x % p) == true
> break
> elif test: # (p > sqrtX) == true
> yield x
> knownPrimes.append(x)
> break
>
Do you know that every prime number is in the form 6*x+1 or 6*x-1, except
2 and 3. This means that instead of checking all odd numbers, you could
loop over 6 numbers then yield n - 1 and n + 1.
def count6(start):
while True:
start += 6
yield start - 1
yield start + 1
And I've seen that you generated prime by dividing things up (actually
modulus). Division and modulus is the slowest arithmetic operator, avoid
it if you can. If you knows the upper bound beforehand, it is faster to
use multiplication and an array of fixed size, i.e. "Sieve of
Erasthotenes". If you intend to generate primes without known upper bound
though, using sieve complexify things up.
More information about the Tutor
mailing list