Confusing performance results for prime
Greg Brunet
gregbrunet at NOSPAMsempersoft.com
Fri Oct 17 16:33:24 EDT 2003
In doing some testing of different but simple algorithms for getting a
list of prime numbers, I ended up getting some results that seem a bit
contradictory. Given the following test program (testPrimes.py) with
two algorithms that both check for primes by testing only odd numbers
using factors up to the square root of the value, where Primes1 is based
on all of the existing primes so far, and Primes2 is based on all odd
numbers, I would expect that, as the number of primes we check gets
larger, that Primes1 should get more & more efficient (since it should
be performing less tests for each number). However the ratio seems to
be relatively consistent. Another thing that is interesting is that
once I tested up to n=200000, I got an exception in Primes2. I added
the long typecast in the 'limit=' statement for both versions and the
resulting improvements were strange: Primes1 runs 10-20% SLOWER, and
Primes2 runs about 50% FASTER!
I am not looking to come up with the most optimized solution to prime
numbers here. Primes1 is faster than Primes2 as I would expect and it
is clear, relatively elegant, and sufficient for me. However, I can't
figure out why the ratio doesn't improve with size, and the strange
results of the long typecast, and I would like to be able to understand
what is causing their behavior. Any ideas? Thanks,
--
Greg
#------------------------------------------------------------
import math, time
def Primes1(y):
primes = [3]
for p in range(5, y, 2):
limit = math.sqrt(p) # or: long(math.sqrt(p))
for factor in primes:
if factor > limit: # then number is prime
primes.append(p)
break
elif p % factor == 0: # then it's *not* prime
break
return [2] + primes
def Primes2(y):
primes = [2,3]
for p in range(5, y, 2):
limit = math.sqrt(p) + 1 # or: long(math.sqrt(p)) + 1
# check one extra to let us see if there were no factors
for n in range(3,limit+3,2):
if p % n == 0: # then it's *not* prime
break
if n > limit:
primes.append(p) # then number is prime
return primes
if __name__ == "__main__":
n=100000
tb = time.time()
l1 = Primes1(n)
t1 = time.time() - tb
print 'Primes1: %s primes up to %s in %5.3f secs' % (len(l1), n, t1)
tb = time.time()
l2 = Primes2(n)
t2 = time.time() - tb
print 'Primes2: %s primes up to %s in %5.3f secs' % (len(l2), n, t2)
print 'ratio: %5.2f' % tt
#------------------------------------------------------------
I get the following results (avg for 3 runs each using Python 2.3.2 on
Win XP Pro):
n=50000 n=100000 n=200000
w/out long:
-----------
Primes1: 0.41 0.95 2.24
Primes2: 1.90 4.21 9.28
Ratio: 4.63 4.42 4.14
w/ long:
-----------
Primes1: 0.48 1.12 2.60
Primes2: 0.84 2.04 4.75
Ratio: 1.75 1.82 1.82
More information about the Python-list
mailing list