What is the difference between the following lines:
if not x == 'val':
Y
if x != 'val':
Is there a way to check if one is more efficient than the other?
Or, maybe the following block would be better:
if x == 'val':
pass
else:
What is the difference between the following lines:
if not x == 'val':
Y
if x != 'val':
Is there a way to check if one is more efficient than the other?
Or, maybe the following block would be better:
if x == 'val':
pass
else:
disassembled
If we use the disassembler for Python (
dis
) , we see that all 3 compile to the same amount of instructions, and only differ in thePOP_JUMP_IF_TRUE
oPOP_JUMP_IF_FALSE
Demo en ideone
profile
Using cProfile , we can measure the execution time and perform a benchmark :
Sorted from slowest to fastest, we can see that:
if not x == 'val'
it is the slowest.if x == 'val'
+else
is ~ 1.7% faster.if x != 'val'
it's ~ 3.6% even faster.Demo en ideone
* Or here is a more complex example to compare true and false cases with random strings.
conclusion
The condition
if x != 'val'
is slightly more efficient.However, in my opinion, the difference is not significant enough to change the style when coding. I absolutely prefer the code to be as easy to read as possible, and I would only think of taking this result into account in extremely intensive calculations that require saving every possible fraction of a second.
All three take the same
Benchmarking is not easy
All three do the same from the point of view of observable behavior. The python compiler or interpreter could therefore generate/execute exactly the same code in all three cases. In which case it would take exactly the same time to execute because it is the same generated code. And the observable differences would be noise.
One might be tempted to disassemble the generated code and see that it is different in all three cases. But the conclusions obtained in this way would only be applicable to the version of python with which the tests have been done. They would not be applicable in general.
Let's observe how using two different methods of executing these instructions we obtain different results. Let us consider the following program:
When executing it with the python interpreter these are the results obtained:
And if I run it multiple times I get similar results. It looks like the winner is not == .
Now I compile it to C with cpython. And the C code I compile to an ELF binary for linux that I execute:
Now sometimes one wins and other times another wins.
But not only can I get different results with different execution environments. With the same execution environment the results can be different depending on the input data. Let's change the line
x='val'
tox='xxx'
and run again with the interpreter:Now it is == else that wins. And when executing it several times this result is repeated. And I'm running it with exactly the same system where before the winner was not == , only the input has changed.
And none of the above benchmarks are good. In all tests the value of
x
is always the same from the beginning to the end of the test. It would also be necessary to test with random data or, better yet, with data obtained from a situation similar to the one that our program is expected to run. We can find surprises such as ordered data being processed faster than random data ; thus removing all value to an excessively simple benchmark as presented above.I think that it is not necessary to compare these comparison operators to determine if one is much more efficient than another, basically because the computation is done so fast that it is almost impossible to detect a difference.
However, in my opinion there are differences when making comparisons with one or the other.
In theory, use
is more efficient than using
The main reason is because != does the comparison directly and asks if x is different from z . Instead, not x == z performs two operations instead of one, because it first checks whether x is equal to z and then negates the result of that operation.
On the other hand, we must take into account the context in which we are making the comparison, in fact, the use of one or the other depends on that. What I mean by this is that there are times when it is much clearer to read and interpret a piece of code with the use of not than with the use of != , an example:
I find the following line of code more readable:
what is this:
And since I am talking about code readability, I would advise not to use reserved words like pass or break because they interrupt the flow of code in a somewhat abrupt way and make it difficult to read, making it complex and incomprehensible. . So much so, that some consider it the Spaghetti Code .
The differences in time I got were extremely minimal, using the following algorithm:
The average was between 12 and 14 thousandths of a second, with
if
TRUE
; and between 9 and 13 milliseconds, withif
FALSE
.The positions from fastest to slowest were as follows:
if
TRUE
if x == 'val'
if x != 'val'
if not x == 'val'
if
FALSE
if x != 'val'
if not x == 'val'
if x == 'val'
According to the Python Data Model
__ne__
, if a class does not implement the method , it delegates to the method__eq__
. Therefore it is assumed more efficient to checka == b
than to checka != b
.On the other hand, a check
if not
is considered a single atomic operation, by design, not because of quirks of the interpreter implementation (as suggested in some comment), just as thenot a is b
and operations were decided to be equivalenta is not b
.So the correct answer should be more efficient
if not x == y
. But this is not true with python native types , since they usually have all the methods of the data model implemented, in addition to their invocation being much more optimized compared to user-created methods.My advice is not to obsess about performance since the improvements come from elsewhere, such as the variables to be compared being local (instead of using global ones) or generating expressions being combined with the functions
any()
orall()
instead of the typical loops with someif
.In my opinion both are the same function, it happens that in the first:
You are conditioning the statement of the condition to negation, that is, if it is NOT true that X is equal to val then do something, run the if, otherwise if it is true that X is VAL then do something else
in the second
You are doing the same but you say:
If X is different from VAL then do something else if X is not equal to VAL then do something else
I seem to work with the method of != different from . since you do not condition from the beginning to negate the entire statement that is in the IF
Additionally, reading about how python works with these two comparators, the first converts it to a boolean, why? Why will it ask the object "Is the logical condition met or not?"
and the second will ask "Are you equal to this value?"
As for your example:
you are declaring if X is equal to the Value do something, the method to use would be based on your need.
to know if the value is equal to the variable to enter the system, X == val
I'm going to give you an answer not based on disassembly, nor time analysis...
As a python programmer, that's pretty much the same to you, 99.99% of the time. It's very rare that something like this is going to affect the speed of your script. In fact, it is even detrimental to waste time on these "micro-optimizations", since there are probably other possible improvements at the algorithmic level.
Even with more complex operations, such as string concatenations, the gains are usually negligible.