Quelle est la différence entre ces deux lignes de code:
if not x == 'val':
et
if x != 'val':
L'un est-il plus efficace que l'autre?
Serait-il préférable d'utiliser
if x == 'val':
pass
else:
python
if-statement
equality
Lafferc
la source
la source
Réponses:
Utilisation
dis
pour regarder le bytecode généré pour les deux versions:not ==
!=
Ce dernier a moins d'opérations et est donc susceptible d'être légèrement plus efficace.
Il a été souligné dans les commentaires (merci, @Quincunx ) que là où vous avez
if foo != bar
vsif not foo == bar
le nombre d'opérations est exactement le même, c'est juste que lesCOMPARE_OP
changements et lesPOP_JUMP_IF_TRUE
commutations versPOP_JUMP_IF_FALSE
:not ==
:!=
Dans ce cas, à moins qu'il n'y ait une différence dans la quantité de travail requise pour chaque comparaison, il est peu probable que vous voyiez une différence de performance.
Cependant, notez que les deux versions ne seront pas toujours logiquement identiques , car cela dépendra des implémentations de
__eq__
et__ne__
pour les objets en question. Selon la documentation du modèle de données :Par exemple:
Enfin, et peut-être le plus important: en général, là où les deux sont logiquement identiques,
x != y
est beaucoup plus lisible quenot x == y
.la source
__eq__
pas cohérente avec__ne__
est complètement cassée.not x == y
ait une instruction de plus. Lorsque j'ai mis le code dans unif
, il s'est avéré qu'ils avaient tous les deux le même nombre d'instructions, une seule avaitPOP_JUMP_IF_TRUE
et l'autrePOP_JUMP_IF_FALSE
(c'était la seule différence entre eux, à part utiliser un autreCOMPARE_OP
). Quand j'ai compilé le code sans leif
s, j'ai ce que vous avez.==
et!=
ne s'excluent pas mutuellement est une implémentation de type SQL impliquant desnull
valeurs. Dans SQLnull
ne revient pastrue
à!=
par rapport à toute autre valeur, de sorte que les implémentations python des interfaces SQL peuvent également avoir le même problème.not ==
et!=
, cela semble être la partie la plus intéressante de ma réponse! Je ne pense pas que ce soit l'endroit sur lequel s'attarder si, pourquoi et quand cela a du sens - voir par exemple Pourquoi Python a-t-il une__ne__
méthode d'opérateur au lieu de juste__eq__
?@jonrsharpe a une excellente explication de ce qui se passe. Je pensais simplement montrer la différence de temps lors de l'exécution de chacune des 3 options 10 000 000 fois (assez pour qu'une légère différence apparaisse).
Code utilisé:
Et les résultats du profileur cProfile:
Nous pouvons donc voir qu'il y a une très infime différence de ~ 0,7% entre
if not x == 'val':
etif x != 'val':
. De ceux-ci,if x != 'val':
est le plus rapide.Cependant, le plus surprenant, nous pouvons voir que
est en fait le plus rapide et bat
if x != 'val':
d'environ 0,3%. Ce n'est pas très lisible, mais je suppose que si vous vouliez une amélioration négligeable des performances, vous pourriez emprunter cette voie.la source
Dans le premier, Python doit exécuter une opération de plus que nécessaire (au lieu de vérifier simplement qu'il n'est pas égal, il doit vérifier si ce n'est pas vrai qu'il est égal, donc une opération de plus). Il serait impossible de faire la différence entre une exécution, mais si elle était exécutée plusieurs fois, la seconde serait plus efficace. Dans l'ensemble, j'utiliserais le second, mais mathématiquement, ce sont les mêmes
la source
Ici, vous pouvez voir qu'il y
not x == y
a une instruction de plus quex != y
. Ainsi, la différence de performances sera très faible dans la plupart des cas, à moins que vous ne fassiez des millions de comparaisons et même dans ce cas, cela ne sera probablement pas la cause d'un goulot d'étranglement.la source
Une note supplémentaire, étant donné que les autres réponses ont généralement répondu correctement à votre question, est que si une classe définit uniquement
__eq__()
et non__ne__()
, alors vousCOMPARE_OP (!=)
l'exécuterez__eq__()
et la nierez. À ce moment-là, votre troisième option sera probablement un peu plus efficace, mais ne devrait être envisagée que si vous avez BESOIN de la vitesse, car elle est difficile à comprendre rapidement.la source
Il s'agit de votre façon de le lire.
not
l'opérateur est dynamique, c'est pourquoi vous pouvez l'appliquer dansMais
!=
pourrait être lu dans un meilleur contexte comme un opérateur qui fait le contraire de ce que==
fait.la source
not
opérateur est dynamique" ?Je souhaite développer mon commentaire sur la lisibilité ci-dessus.
Encore une fois, je suis entièrement d'accord avec le fait que la lisibilité l'emporte sur d'autres préoccupations (non significatives en termes de performances).
Ce que je voudrais souligner, c'est que le cerveau interprète «positif» plus vite que «négatif». Par exemple, "arrêter" contre "ne pas y aller" (un exemple plutôt moche en raison de la différence de nombre de mots).
Alors donné le choix:
est préférable à l'équivalent fonctionnel:
Moins de lisibilité / compréhensibilité entraîne plus de bogues. Peut-être pas dans le codage initial, mais la maintenance (pas aussi intelligente que vous!) Change ...
la source