filter2

Delaney, Timothy tdelaney at avaya.com
Sun Jun 16 20:59:58 EDT 2002


# Baseline 1
def filter2a (test, l):
    l1 = filter(test, l)
    l2 = filter(lambda x, test=test: not test(x), l)
    return l1, l2

# Baseline 2
def filter2b (test, l):
    l1 = []
    l2 = []
    l1append = l1.append
    l2append = l2.append

    for x in l:
        if test(x):
            l1append(x)
        else:
            l2append(x)

    return l1, l2
 
# Based on Jeff Epler's - won't work < Python 2.0
def filter2t (test, l):
    l1 = []
    l2 = []
    funcs = (l1.append, l2.append,)
    map(lambda x: funcs[not test(x)](x), l)
    return l1, l2

# Based on Jeff Epler's - won't work < Python 2.0
def filter2l (test, l):
    l1 = []
    l2 = []
    funcs = [l1.append, l2.append,]
    map(lambda x: funcs[not test(x)](x), l)
    return l1, l2

# Based on Jeff Epler's
def filter3t (test, l):
    l1 = []
    l2 = []
    map(lambda x, test=test, funcs=(l1.append, l2.append,): funcs[not
test(x)](x), l)
    return l1, l2

# Based on Jeff Epler's
def filter3l (test, l):
    l1 = []
    l2 = []
    map(lambda x, test=test, funcs=[l1.append, l2.append,]: funcs[not
test(x)](x), l)
    return l1, l2

# Based on Bengt Richter's - won't work < Python 2.0
def filter4 (test, l):
    l2 = []
    append = l2.append
    return [x for x in l if test(x) or append(x)], l2
 
# Based on Bengt Richter's
def filter5 (test, l):
    l2 = []
    return filter(lambda x, test=test, append=l2.append: test(x) or
append(x), l), l2

import operator

def test (x, truth=operator.truth):
    return truth(x)

def bench (f, r, l, t):
    """"""
    import time
    clock = time.clock

    start = clock()
    for i in r:
        f(t, l)
    t = clock() - start
    print '%-10s %s' % (f.__name__ + ':', t,)

r = range(1000)
l = range(1000)
filters = (filter2a, filter2b, filter2t, filter2l, filter3t, filter3l,
filter4, filter5,)

print 'Python function'
print
for func in filters:
    bench(func, r, l, test)

print
print 'C function'
print
for func in filters:
    bench(func, r, l, operator.truth)

---
Python 2.2.1 Windows 2000

Python function

filter2a:  6.18176173589
filter2b:  3.81115916127
filter2t:  4.99432009837
filter2l:  4.9499274483
filter3t:  4.8721376543
filter3l:  4.75815178722
filter4:   3.86890220203
filter5:   3.73075037996

C function

filter2a:  3.6114880356
filter2b:  2.18989099755
filter2t:  3.73375104874
filter2l:  3.60997196065
filter3t:  3.68825664697
filter3l:  3.58173029097
filter4:   2.21596360152
filter5:   2.64008410331

So, the most naive version (with common optimisations) works fastest for C
functions (operator.truth *is* a C function, isn't it?) but the difference
is minimal, Bengt's works fastest for Python functions with a fair
difference. I actually expected it to be the other way around ... 

Tim Delaney





More information about the Python-list mailing list