Function application optimization.

Duncan Booth duncan at NOSPAMrcp.co.uk
Fri Dec 12 09:19:08 EST 2003


"John Roth" <newsgroups at jhrothjr.com> wrote in 
news:vtjhmt7idn3k6b at news.supernews.com:

> Building on a couple of other responses:
> 
> Untested code:
> 
> fncs = [func1, func2, ..., funcN]
> args = [arg1,  arg2,  ..., argN]
> results = []
> for function, arguement in zip(fncs, args):
>     results.append(function(arguement))
> 
> Notice the use of zip() to put the two lists together.
> I haven't timed it, but removing an extra layer of
> function call has got to be faster. Likewise, zip
> and tuple unpacking is most likely going to be
> faster than indexing every time through the loop.
> The append, on the other hand, might slow things
> down a bit.

Yes, getting rid of the append does indeed speed things up. On the same 
system as I posted timings for the list comprehension, the fastest way I've 
found so far is to get rid of the appends by preallocating the list, and to  
go for the plain old simple technique of writing a for loop out explicitly. 
Using 'enumerate' to avoid the lookup on one of the input lists is nearly 
as fast, but not quite.

>>> setup = """import itertools
def fn1(a): pass
fns = [fn1] * 1000
args = [0] * 1000
"""

>>> stmt1 = """result = args[:]
for i in range(len(fns)):
 result[i] = fns[i](args[i])
"""
>>> min(timeit.Timer(stmt1, setup).repeat(3,1000))
2.9747384094916924
>>> stmt3 = "results = map(lambda f,a: f(a), fns, args)"
>>> min(timeit.Timer(stmt3, setup).repeat(3,1000))
3.3257092731055309
>>> 

-- 
Duncan Booth                                             duncan at rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?




More information about the Python-list mailing list