Still too slow

Philip Semanchuk philip at semanchuk.com
Sun Jan 31 00:31:41 CET 2010


On Jan 30, 2010, at 6:08 PM, elsa wrote:

> Hello again,
>
> Thanks for the tips r.e random.ranint(). This improved matters
> somewhat, however my program is still too slow. If anyone has any
> further tips on how to speed it up, they would be much appreciated!
>
> So, I'm calling evolve(L,limit) from the interactive prompt. L is
> initally [[100],['NA']]. Ideally limit would be 10^7.
>
> Here is my program:
>
> import random
> n=100
>
> def evolve(L,limit):
> 	global n
> 	while n<limit:
> 		evnt = event()
> 		if evnt!="None":
> 			ind = chooseInd(L,n)
> 			action(evnt,L,ind)
>
> def chooseInd(L,n):
> 	choiceSum=0
> 	index=0
> 	choice = random.randint(1,n)
> 	while choiceSum < choice:
> 		choiceSum+=L[index][0]
> 		index +=1
> 	return (index-1)
>
> def event():
> 	choice = random.random()
> 	if choice <= .3:
> 		event='b'
> 	elif choice <= .4:
> 		event ='d'
> 	elif choice<= .5:
> 		event = 'm'
> 	else:
> 		event = 'None'
> 	return event
>
> def action(event, L, index):
> 	global n
> 	if event == 'b':
> 		L[index][0]+=1
> 		n +=1
> 	elif event == 'd':
> 		L[index][0]-=1
> 		n -=1
> 	elif event == 'm':
> 		L.append([1,index])
> 		n +=1

Hi Elsa,
I didn't follow the earlier discussion on this, so pardon me if I'm  
repeating what others have said.

First, have you profiled the code? That will help you find bottlenecks.

I haven't profiled it myself so I am shooting from the hip, but a  
couple of obvious speedups in event() jump out at me. I'd rewrite it  
like this:

def event():
     choice = random.random()
     if choice <= .3:
         return 'b'
     elif choice <= .4:
         return 'd'
     elif choice <= .5:
         return 'm'

     return None

Returning immediately when you've found your choice will save  
evaluating a couple of elifs -- not a big help, but it is a little. It  
comes at the cost having multiple exits to the function which is  
something I  prefer to avoid, but this function is small enough that  
having multiple exits won't get confusing.

Second, returning the Python object None rather than the string "None"  
allows you to change evolve() from this string comparison:
    if evnt!="None":

to this comparison to the Python singleton None:
    if evnt != None:

or this, which is even simpler (although it may not be faster):
    if evnt:

Hope this helps
Philip




More information about the Python-list mailing list