¿Cuál es la diferencia entre estas dos líneas de código?
if not x == 'val':
y
if x != 'val':
¿Es uno más eficiente que el otro?
¿Sería mejor usar
if x == 'val':
pass
else:
python
if-statement
equality
lafferc
fuente
fuente
Respuestas:
Utilizando
dis
para mirar el bytecode generado para las dos versiones:not ==
!=
Este último tiene menos operaciones y, por lo tanto, es probable que sea un poco más eficiente.
Se señaló en los comentarios (gracias, @Quincunx ) que donde tienes
if foo != bar
frente aif not foo == bar
la cantidad de operaciones es exactamente la misma, es solo que losCOMPARE_OP
cambios yPOP_JUMP_IF_TRUE
cambios aPOP_JUMP_IF_FALSE
:not ==
:!=
En este caso, a menos que haya una diferencia en la cantidad de trabajo requerido para cada comparación, es poco probable que vea alguna diferencia de rendimiento.
Sin embargo, tenga en cuenta que las dos versiones no siempre serán lógicamente idénticas , ya que dependerá de las implementaciones de
__eq__
y__ne__
para los objetos en cuestión. Según la documentación del modelo de datos :Por ejemplo:
Finalmente, y quizás lo más importante: en general, donde los dos son lógicamente idénticos,
x != y
es mucho más legible quenot x == y
.fuente
__eq__
inconsistente con__ne__
está completamente rota.not x == y
tenga una instrucción más. Cuando puse el código en unif
, resultó que ambos tienen la misma cantidad de instrucciones, solo una teníaPOP_JUMP_IF_TRUE
y la otraPOP_JUMP_IF_FALSE
(esa era la única diferencia entre ellas, aparte de usar una diferenteCOMPARE_OP
). Cuando compilé el código sin elif
s, obtuve lo que tienes.==
y!=
no son mutuamente excluyentes es una implementación tipo SQL que involucranull
valores. En SQLnull
no se vuelvetrue
a!=
comparar con ningún otro valor, por lo que las implementaciones de Python de interfaces SQL también pueden tener el mismo problema.not ==
y!=
, ¡parece ser la parte más interesante de mi respuesta! No creo que este sea el lugar en el que pensar si, por qué y cuándo tiene sentido, ver, por ejemplo, ¿__ne__
__eq__
@jonrsharpe tiene una excelente explicación de lo que está sucediendo. Pensé que solo mostraría la diferencia en el tiempo al ejecutar cada una de las 3 opciones 10,000,000 de veces (suficiente para mostrar una ligera diferencia).
Código usado:
Y los resultados del perfilador cProfile:
Entonces podemos ver que hay una diferencia muy pequeña de ~ 0.7% entre
if not x == 'val':
yif x != 'val':
. De estos,if x != 'val':
es el más rápido.Sin embargo, lo más sorprendente es que podemos ver que
es, de hecho, el más rápido y late
if x != 'val':
en ~ 0.3%. Esto no es muy legible, pero supongo que si quisieras una mejora insignificante del rendimiento, uno podría seguir esta ruta.fuente
En el primero, Python tiene que ejecutar una operación más de la necesaria (en lugar de simplemente verificar que no sea igual, tiene que verificar si no es cierto que sea igual, por lo tanto, una operación más). Sería imposible distinguir la diferencia de una ejecución, pero si se ejecuta muchas veces, la segunda sería más eficiente. En general, usaría el segundo, pero matemáticamente son lo mismo
fuente
Aquí puedes ver que
not x == y
tiene una instrucción más quex != y
. Por lo tanto, la diferencia de rendimiento será muy pequeña en la mayoría de los casos, a menos que esté haciendo millones de comparaciones e incluso entonces esto probablemente no sea la causa de un cuello de botella.fuente
Una nota adicional, dado que las otras respuestas respondieron su pregunta en su mayoría correctamente, es que si una clase solo define
__eq__()
y no__ne__()
, entonces laCOMPARE_OP (!=)
ejecutará__eq__()
y la negará. En ese momento, es probable que su tercera opción sea un poco más eficiente, pero solo debe considerarse si NECESITA la velocidad, ya que es difícil de entender rápidamente.fuente
Se trata de tu forma de leerlo.
not
el operador es dinámico, por eso puede aplicarlo enPero
!=
podría leerse en un mejor contexto como un operador que hace lo contrario de lo que==
hace.fuente
not
operador es dinámico" ?Quiero ampliar mi comentario de legibilidad anterior.
Nuevamente, estoy completamente de acuerdo con la legibilidad que anula otras preocupaciones (insignificantes en cuanto al rendimiento).
Lo que me gustaría señalar es que el cerebro interpreta "positivo" más rápido que "negativo". Por ejemplo, "parar" frente a "no ir" (un ejemplo bastante pésimo debido a la diferencia en el número de palabras).
Entonces, dado una opción:
es preferible al funcionalmente equivalente:
Menos legibilidad / comprensibilidad conduce a más errores. Quizás no en la codificación inicial, pero los cambios de mantenimiento (¡no tan inteligentes como usted!) ...
fuente