Qual é a diferença entre essas duas linhas de código:
if not x == 'val':
e
if x != 'val':
Um é mais eficiente que o outro?
Seria melhor usar
if x == 'val':
pass
else:
python
if-statement
equality
lafferc
fonte
fonte
Respostas:
Utilizando
dis
para olhar o bytecode gerado para as duas versões:not ==
!=
Este último possui menos operações e, portanto, provavelmente será um pouco mais eficiente.
Foi indicado nos comentários (obrigado, @Quincunx ) que onde você tem
if foo != bar
vs.if not foo == bar
o número de operações é exatamente o mesmo, é só que asCOMPARE_OP
alterações e as mudançasPOP_JUMP_IF_TRUE
paraPOP_JUMP_IF_FALSE
:not ==
:!=
Nesse caso, a menos que haja uma diferença na quantidade de trabalho necessária para cada comparação, é improvável que você veja alguma diferença de desempenho.
No entanto, observe que as duas versões nem sempre serão logicamente idênticas , pois dependerão das implementações
__eq__
e__ne__
dos objetos em questão. Por a documentação do modelo de dados :Por exemplo:
Finalmente, e talvez o mais importante: em geral, onde os dois são logicamente idênticos,
x != y
é muito mais legível do quenot x == y
.fonte
__eq__
inconsistente__ne__
é completamente quebrada.not x == y
há mais uma instrução. Quando eu coloquei o código em umif
, descobriu-se que os dois tinham o mesmo número de instruções, apenas um tinhaPOP_JUMP_IF_TRUE
e o outroPOP_JUMP_IF_FALSE
(essa era a única diferença entre eles, além de usar um diferenteCOMPARE_OP
). Quando compilei o código sem osif
s, obtive o que você conseguiu.==
e!=
não são mutuamente exclusivos é uma implementação semelhante a SQL envolvendonull
valores. Em SQLnull
não retornatrue
a!=
comparação com qualquer outro valor, então implementações de python de interfaces SQL também podem ter o mesmo problema.not ==
e!=
, parece ser a parte mais interessante da minha resposta! Eu não acho que este seja o lugar para pensar se, por que e quando isso faz sentido - veja, por exemplo, por que o Python tem um__ne__
método de operador em vez de apenas__eq__
?@jonrsharpe tem uma excelente explicação do que está acontecendo. Eu pensei em mostrar a diferença no tempo ao executar cada uma das três opções 10.000.000 de vezes (o suficiente para mostrar uma pequena diferença).
Código usado:
E o perfil do cProfile resulta:
Portanto, podemos ver que há uma diferença muito pequena de ~ 0,7% entre
if not x == 'val':
eif x != 'val':
. Destes,if x != 'val':
é o mais rápido.Surpreendentemente, porém, podemos ver que
é de fato o mais rápido e supera
if x != 'val':
em ~ 0,3%. Isso não é muito legível, mas acho que se você quiser uma melhoria insignificante de desempenho, poderá seguir esse caminho.fonte
No primeiro, o Python precisa executar mais uma operação do que o necessário (em vez de apenas verificar não igual a ele, deve verificar se não é verdade que é igual, portanto, mais uma operação). Seria impossível distinguir a diferença de uma execução, mas se executada muitas vezes, a segunda seria mais eficiente. No geral, eu usaria o segundo, mas matematicamente eles são os mesmos
fonte
Aqui você pode ver que
not x == y
tem mais uma instrução quex != y
. Portanto, a diferença de desempenho será muito pequena na maioria dos casos, a menos que você esteja fazendo milhões de comparações e mesmo assim isso provavelmente não será a causa de um gargalo.fonte
Uma observação adicional, uma vez que as outras respostas responderam à sua pergunta principalmente corretamente, é que, se uma classe apenas define
__eq__()
e não__ne__()
, então vocêCOMPARE_OP (!=)
a executará__eq__()
e a negará. Nesse momento, sua terceira opção provavelmente será um pouco mais eficiente, mas só deve ser considerada se você precisar da velocidade, pois é difícil entender rapidamente.fonte
É sobre a sua maneira de lê-lo.
not
operador é dinâmico, é por isso que você pode aplicá-loMas
!=
poderia ser lido em um contexto melhor como um operador que faz o oposto do que==
faz.fonte
not
operador é dinâmico" ?Quero expandir meu comentário de legibilidade acima.
Mais uma vez, concordo plenamente com a legibilidade, substituindo outras preocupações (insignificantes de desempenho).
O que eu gostaria de salientar é que o cérebro interpreta "positivo" mais rapidamente do que "negativo". Por exemplo, "parar" vs. "não seguir" (um exemplo bastante ruim devido à diferença no número de palavras).
Então, dada uma escolha:
é preferível ao funcionalmente equivalente:
Menos legibilidade / compreensão leva a mais erros. Talvez não na codificação inicial, mas a manutenção (não tão inteligente quanto você!) Muda ...
fonte