suppressing import errors
Chris Kaynor
ckaynor at zindagigames.com
Tue Nov 15 17:22:21 EST 2011
On Tue, Nov 15, 2011 at 1:34 PM, Chris Angelico <rosuav at gmail.com> wrote:
> On Wed, Nov 16, 2011 at 8:20 AM, David Riley <fraveydank at gmail.com> wrote:
>> Comparisons to singletons like None should always be done with
>> 'is' or 'is not', never the equality operators.
>>
>> Also, beware of writing "if x" when you really mean "if x is not None"
>> -- e.g. when testing whether a variable or argument that defaults to
>> None was set to some other value. The other value might have a type
>> (such as a container) that could be false in a boolean context!
>
> It's probably quicker to execute "if x is None" than "if x"
> (presumably the former just compares the two pointers). On the other
> hand, it's more compact to leave off the "is None". And on the
> gripping hand, neither "quicker to execute" nor "more compact" equates
> to "more Pythonic".
I decided to run some tests to see which is faster. As is turns out,
in simple cases (eg, True), "if x: pass" is faster than "if x is None:
pass" if x is True, and otherwise its the same. If x is a custom type
(I only tested a simple custom class written in Python), "if x is
None: pass" is significantly faster.
Overall, performance-wise, it is irrelevant - use the code that is the
most clear in the situation. Only if there is a custom type involved,
and then only if that type defines Python code to be executed, does it
matter.
The tests (the code is shown later - its about 53 lines, with lots of
copy+paste...):
1a: 0.04 usec/pass -- if None: pass
1b: 0.03 usec/pass -- if True: pass
1c: 0.27 usec/pass -- if customObjectWithNonZero: pass
1d: 0.04 usec/pass -- if customObjectNoNonZero: pass
2a: 0.04 usec/pass -- if None is None: pass
2b: 0.04 usec/pass -- if True is None: pass
2c: 0.04 usec/pass -- if customObjectWithNonZero is None: pass
2d: 0.04 usec/pass -- if customObjectNoNonZero is None: pass
The tests were run on Python 2.6x64 on Windows:
2.6.4 (r264:75706, Aug 4 2010, 17:00:56) [MSC v.1500 64 bit (AMD64)]
The code:
import timeit
def test():
numRuns = 10000000
statement1 = 'if x: pass'
statement2 = 'if x is None: pass'
setup1 = 'x = None'
setup2 = 'x = True'
setup3 = '''
class Test(object):
def __nonzero__(self):
return True
x = Test()'''
setup4 = '''
class Test(object):
pass
x = Test()'''
t1a = timeit.Timer(stmt=statement1, setup=setup1)
t1b = timeit.Timer(stmt=statement1, setup=setup2)
t1c = timeit.Timer(stmt=statement1, setup=setup3)
t1d = timeit.Timer(stmt=statement1, setup=setup4)
t2a = timeit.Timer(stmt=statement2, setup=setup1)
t2b = timeit.Timer(stmt=statement2, setup=setup2)
t2c = timeit.Timer(stmt=statement2, setup=setup3)
t2d = timeit.Timer(stmt=statement2, setup=setup4)
a1 = []
b1 = []
c1 = []
d1 = []
a2 = []
b2 = []
c2 = []
d2 = []
for i in xrange(10):
a1.append(1000000 * t1a.timeit(number=numRuns)/numRuns)
b1.append(1000000 * t1b.timeit(number=numRuns)/numRuns)
c1.append(1000000 * t1c.timeit(number=numRuns)/numRuns)
d1.append(1000000 * t1d.timeit(number=numRuns)/numRuns)
a2.append(1000000 * t2a.timeit(number=numRuns)/numRuns)
b2.append(1000000 * t2b.timeit(number=numRuns)/numRuns)
c2.append(1000000 * t2c.timeit(number=numRuns)/numRuns)
d2.append(1000000 * t2d.timeit(number=numRuns)/numRuns)
print "1a: %.2f usec/pass" % (sum(a1) / len(a1),)
print "1b: %.2f usec/pass" % (sum(b1) / len(b1),)
print "1c: %.2f usec/pass" % (sum(c1) / len(c1),)
print "1d: %.2f usec/pass" % (sum(d1) / len(d1),)
print "2a: %.2f usec/pass" % (sum(a2) / len(a2),)
print "2b: %.2f usec/pass" % (sum(b2) / len(b2),)
print "2c: %.2f usec/pass" % (sum(c2) / len(c2),)
print "2d: %.2f usec/pass" % (sum(d2) / len(d2),)
>
> ChrisA
> --
> http://mail.python.org/mailman/listinfo/python-list
>
More information about the Python-list
mailing list