Re: [Tutor] Help Optimise Code

2008-12-04 Thread J�rg W�lke
* Richard Lovely [EMAIL PROTECTED] [081123 11:35]:
 I've tried a the sieve of erath-whatever as in test_generator,
 implemented using itertools functions, but it hit max recusion depth
 somewhere before 1000 primes, and I'm after millions of primes.

I found an old implementation for some exercise of the 
sieve of Eratosthenes in my backups and its not recursive but 
iterative:

#!/usr/bin/env python

l=1*[1]
for i in range(2,len(l)):
if l[i] == 1:
   print i
   for j in range(i+1,len(l)):
   if j%i == 0:
   l[j]=0

Yes, it is pretty slow for a range of a million, but it speeds up 
a little after half an hour or so :-)
You might want to have a look at the bsd-games package, which
includes a program named primes. It prints out primes at a 
reasonable speed - up to 4294967295 (the default). The manpage says:

BUGS
 primes won't get you a world record.

If you can get it to work faster in python? I doubt that.
primes uses IIRC atkin-sieve: http://cr.yp.to/papers/primesieves.pdf;

-- 
You have an ambitious nature and may make a name for yourself.

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help Optimise Code

2008-12-04 Thread Kent Johnson
On Thu, Dec 4, 2008 at 11:38 AM, Jörg Wölke [EMAIL PROTECTED] wrote:

 #!/usr/bin/env python

 l=1*[1]
 for i in range(2,len(l)):
if l[i] == 1:
   print i
   for j in range(i+1,len(l)):
   if j%i == 0:

for j in range(2*i, len(l), i):
would be much faster, avoiding all the division.

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help Optimise Code

2008-11-21 Thread Rich Lovely
On a small side note, the docs say array.array is supposed to be  
efficient.  Testing has shown in this function, a list is faster (at  
least for x10). A set is faster still - at least over the same  
range on my computer,, but you can't guarantee ordering, which makes  
it inconsistent - and potentially broken.


The version I've got in my original post (using a single variable and  
short-circuiting logic) is almost twice as fast as the version using  
two separate tests.  I don't know why, so suggestions would be  
appreciated.


I'll add in a version of the count6 function. I must have forgotten  
that maths lesson.


I've just thought of something that might be faster than using mod,  
but I'll have to wait until I get home to test it.
(using a list of itertools.cycle's to produce a true/false from a  
tuple with prime length, yielding a number iff not any(l[:sqrtX]). No  
division involved...) If that make no sense to anyone, it makes less  
sense to me, sounds ok, though...

---
Richard Roadie Rich Lovely
Part of the JNP|UK Famille
www.theJNP.com

(Sent from my iPod - please allow me a few typos: it's a very small  
keyboard)


On 19 Nov 2008, at 09:26 PM, Lie Ryan [EMAIL PROTECTED] wrote:


On Wed, 19 Nov 2008 13:13:18 +, 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.

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help Optimise Code

2008-11-21 Thread Kent Johnson
On Wed, Nov 19, 2008 at 8:13 AM, Richard Lovely
[EMAIL PROTECTED] wrote:

 Please don't suggest changing languages. I like python. Although if
 you want to write an extension for me, and provide the source and a
 makefile, please feel free. I have a MinGW install that's doing
 nothing.  (Just kidding - almost.)

Take a look at psyco, Cython, ShedSkin, Pyrex...

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


[Tutor] Help Optimise Code

2008-11-19 Thread Richard Lovely
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
knownPrimes = array.array(L,(3,5)) # 'L' for unsigned long - not
tested if using a smaller type is faster
for x in count2(7):
sqrtX = sqrt(x) # take extra function calls out of the inner loop
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


I've tried a the sieve of erath-whatever as in test_generator,
implemented using itertools functions, but it hit max recusion depth
somewhere before 1000 primes, and I'm after millions of primes.

I'm not particularly bothered about startup overheads, just the loops.

Quick thought: would the following work (I'm on a public computer
without python, so can't test):

Code: Select all
def iprimes():
'generate an endless sequence of prime numbers'
yield 2
yield 3
yield 5
sqrt = math.sqrt
knownPrimes = array.array(L,(3,5)) # 'L' for unsigned long - not
tested if using a smaller type is faster
for x in count2(7):
sqrtX = sqrt(x) # take extra function calls out of the inner loop
for test in ((not x % p) and -1 or p  sqrtX for p in
knownPrimes)): # a generator _should_ be faster...
if test == -1: # (not x % p) == true
break
elif test: # (p  sqrtX) == true
yield x
knownPrimes.append(x)
break


Please don't suggest changing languages. I like python. Although if
you want to write an extension for me, and provide the source and a
makefile, please feel free. I have a MinGW install that's doing
nothing.  (Just kidding - almost.)

This is NOT homework.

-- 
Richard Roadie Rich Lovely, part of the JNP|UK Famile
www.theJNP.com
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help Optimise Code

2008-11-19 Thread Kent Johnson
On Wed, Nov 19, 2008 at 8:13 AM, Richard Lovely
[EMAIL PROTECTED] 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.


You might be interested in this recipe and discussion:
http://code.activestate.com/recipes/366178/

According to Wikipedia, the siev of Atkin is faster than sieve of Eratosthenes:
http://en.wikipedia.org/wiki/Sieve_of_Atkin

 This is what I've got so far:

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

You are duplicating your tests, why not
if (not x % p):
  break
elif p  sqrtX:
  ...
?

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help Optimise Code

2008-11-19 Thread Lie Ryan
On Wed, 19 Nov 2008 13:13:18 +, 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.

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor