[Edu-sig] Using try / except: any stipulations against routine use?

David Handy david at handysoftware.com
Thu Dec 15 03:20:21 CET 2011


On Wed, Dec 14, 2011 at 08:59:58PM -0400, Andre Roberge wrote:
> Personally, I find both the if/else and the try/except much easier to
> remember, and slightly easier to read than the one-liner.
> 
> Furthermore, if one is interested in performance, it appears that the
> if/else approach is *always* faster than the one-liner.  When exceptions
> are rarely raised, then the try/except approach is the fastest.   Below are
> the results from a quick test to compare the efficiency of the three cases,
> followed by the code.  This is using Python 2.7 on a fairly old computer.
> 
> André

(Snipped André's code and results.)

Thanks for the benchmark!

For readability, my very favorite is to use defaultdict, in Python since
version 2.5:

from collections import defaultdict

d = defaultdict(int)
d[k] += 1

I added a defaultdict case to André's benchmark. It definitely beats
setdefault and is competitive with both try/except and if/else.  This was
also run using Python 2.7 on my very slow notebook PC.

David H

===============================

100% new keys

setdefault:     0.821501894794
defaultdict:    0.96327996994
try/except:     3.30088125725
if/else:        0.400257295271
--------------------------------------------------
10% new keys
setdefault:     1.07847561631
defaultdict:    0.656087296011
try/except:     0.980378791159
if/else:        0.600138006367
--------------------------------------------------
1% new keys

setdefault:     1.08054654991
defaultdict:    0.604530464067
try/except:     0.711149322051
if/else:        0.605315759405
--------------------------------------------------
0.1% new keys

setdefault:     0.848571815692
defaultdict:    0.395037078735
try/except:     0.482041712005
if/else:        0.570016859685

===============================

from timeit import Timer

print "100% new keys\n"
print 'setdefault:\t',
t = Timer("""
d = {}
for i in range(1000):
    d[i] = d.get(i, 0) + 1
""")
print t.timeit(number=1000)

print 'defaultdict:\t',
t = Timer("""
d = defaultdict(int)
for i in range(1000):
    d[i] += 1
""", setup='from collections import defaultdict')
print t.timeit(number=1000)

print 'try/except:\t',
t = Timer("""
d = {}
for i in range(1000):
    try:
        d[i] += 1
    except KeyError:
        d[i] = 1
""")
print t.timeit(number=1000)

print 'if/else:\t',
t = Timer("""
d = {}
for i in range(1000):
    if i in d:
        d[i] += 1
    else:
        d[i] = 1
""")
print t.timeit(number=1000)

print "-"*50
print "10% new keys"
print 'setdefault:\t',
t = Timer("""
d = {}
for i in range(1000):
    k = i % 100
    d[k] = d.get(k, 0) + 1
""")
print t.timeit(number=1000)

print 'defaultdict:\t',
t = Timer("""
d = defaultdict(int)
for i in range(1000):
    k = i % 100
    d[k] += 1
""", setup='from collections import defaultdict')
print t.timeit(number=1000)

print 'try/except:\t',
t = Timer("""
d = {}
for i in range(1000):
    k = i % 100
    try:
        d[k] += 1
    except KeyError:
        d[k] = 1
""")
print t.timeit(number=1000)

print 'if/else:\t',
t = Timer("""
d = {}
for i in range(1000):
    k = i % 100
    if i in d:
        d[k] += 1
    else:
        d[k] = 1
""")
print t.timeit(number=1000)

print "-"*50
print "1% new keys\n"
print 'setdefault:\t',
t = Timer("""
d = {}
for i in range(1000):
    k = i % 10
    d[k] = d.get(k, 0) + 1
""")
print t.timeit(number=1000)

print 'defaultdict:\t',
t = Timer("""
d = defaultdict(int)
for i in range(1000):
    k = i % 10
    d[k] += 1
""", setup='from collections import defaultdict')
print t.timeit(number=1000)

print 'try/except:\t',
t = Timer("""
d = {}
for i in range(1000):
    k = i % 10
    try:
        d[k] += 1
    except KeyError:
        d[k] = 1
""")
print t.timeit(number=1000)

print 'if/else:\t',
t = Timer("""
d = {}
for i in range(1000):
    k = i % 10
    if i in d:
        d[k] += 1
    else:
        d[k] = 1
""")
print t.timeit(number=1000)


print "-"*50
print "0.1% new keys\n"
print 'setdefault:\t',
t = Timer("""
d = {}
for i in range(1000):
    d[1] = d.get(1, 0) + 1
""")
print t.timeit(number=1000)

print 'defaultdict:\t',
t = Timer("""
d = defaultdict(int)
for i in range(1000):
    d[1] += 1
""", setup='from collections import defaultdict')
print t.timeit(number=1000)

print 'try/except:\t',
t = Timer("""
d = {}
for i in range(1000):
    try:
        d[1] += 1
    except KeyError:
        d[1] = 1
""")
print t.timeit(number=1000)

print 'if/else:\t',
t = Timer("""
d = {}
for i in range(1000):
    if 1 in d:
        d[1] += 1
    else:
        d[1] = 1
""")
print t.timeit(number=1000)



More information about the Edu-sig mailing list