问题
Does it matter how I order the conditions in Python in respect to the speed of the script? In SQL e.g. it does not as the "Interpreter" assumes which condition ordering would be the fastest.
In Python, as far as I know, the order of conditions will be taken as given by the interpreter. So as an example, if I chain or-conditions, is it better to order the conditions by assumed time they will consume because maybe the interpreter stops even looking for the other conditions when the first one doesn't apply anyway?
回答1:
Yes, the order of conditions matters. They are evaluated left-to-right unless you change that by using parentheses, for example.
And yes, conditions are only evaluated if the outcome of the expression isn't already clear. For example, in
if 1==0 and foo**10000 > 2:
Python will return False
immediately and not even attempt to calculate foo**10000
.
回答2:
Python will not reorder your conditions like in SQL, but it will short circuit. What this means is that it will stop evaluating as soon as possible. So if you have if True == True or long_function_call():
, long_function_call()
will never be evaluated. This works similarly for and
with something like if True == False and long_function_call():
. It would be in your best interest to consider this when writing conditional statements and can result in changes in performance.
回答3:
Boolean operators in Python are short-circuiting - as soon as the result of an expression is clear, evaluation stops. This plays an important role in Python's late-binding.
For example, this is a common check:
def do(condition_check=None):
if condition_check is not None and condition_check():
# do stuff
Python is in general very conservative about premature optimizations. If there is any chance that something might break, Python will not try it.
If you want to check Interpreter optimizations, try the dis
module. It shows the instructions actually being run by the Python core. For example, Python will resolve constant expressions (10**10
=> 10000000000
) and back out of an and
early (JUMP_IF_FALSE_OR_POP
).
dis.dis('1==0 and 10**10 > 2')
1 0 LOAD_CONST 0 (1)
3 LOAD_CONST 1 (0)
6 COMPARE_OP 2 (==)
9 JUMP_IF_FALSE_OR_POP 21
12 LOAD_CONST 4 (10000000000)
15 LOAD_CONST 3 (2)
18 COMPARE_OP 4 (>)
>> 21 RETURN_VALUE
Note that not even pypy does any further optimization on this code!
来源:https://stackoverflow.com/questions/39946279/does-the-order-of-conditions-affect-performance