a_guest
a_guest

Reputation: 36309

Using tuples instead of boolean operators

Is there a difference (in terms of performance, not readability) between the following ways of evaluating two (or more) conditions linked by and?

a == 1 and b == 2

or

(a,b) == (1,2)


The same for or:

a == 1 or b == 1

or

1 in (a,b)


Which way is preferable? The one using boolean operators or the other one using tuples?

Upvotes: 2

Views: 123

Answers (3)

Padraic Cunningham
Padraic Cunningham

Reputation: 180481

These are some timings using python 2.7

In [29]: a = 1 

In [30]: b = 2

In [31]: timeit a == 1 and b == 2
10000000 loops, best of 3: 82.2 ns per loop

In [32]: timeit (a,b) == (1,2)
10000000 loops, best of 3: 132 ns per loop

In [33]: timeit 1 in (a,b)
10000000 loops, best of 3: 118 ns per loop

And when the outcome is False:

In [37]: timeit a == 2 and b == 2
10000000 loops, best of 3: 52.2 ns per loop

In [38]: timeit 3 in (a,b)
10000000 loops, best of 3: 151 ns per loop

In [39]: timeit (a,b) == (2,2)
10000000 loops, best of 3: 144 ns per loop

a == 2 and b == 2 is faster as and is a short circuit operator

As per wim's comment using a set will be faster than checking the tuple for membership:

In [55]: timeit 3 in {a,b}
10000000 loops, best of 3: 92.9 ns per loop

Upvotes: 4

wim
wim

Reputation: 363203

Yes, there is a logical difference in that that using and/or are short-circuiting.

>>> def return1():
...     return 1
... 
>>> def raises():
...     raise Exception('uh oh')
... 
>>> a, b = 1, 2
>>> a == return1() or b == raises()
True
>>> b == return1() and a == raises()
False

Note the function which raises exception never gets called. In both the other examples, we will have an unhandled exception:

>>> a, b == return1(), raises()
# raises Exception
>>> 1 in (return1(), raises())
# raises Exception .. 

In the case of literals, this obviously doesn't make any difference to the flow and any performance differences are likely to be negligible. I prefer the second style in this case.

Upvotes: 3

Joohwan
Joohwan

Reputation: 2512

Using and/or operators are almost always better in terms of performance (perhaps not for readability but that's another issue): 1. They avoid having to create tuple objects like you do in other examples which will be more costly in terms of space/time complexity 2. They short-circuit meaning there is a good chance you can avoid executing unnecessary portions of the code.

Upvotes: 3

Related Questions