В чем разница между этими двумя строками кода:
if not x == 'val':
и
if x != 'val':
Один эффективнее другого?
Было бы лучше использовать
if x == 'val':
pass
else:
python
if-statement
equality
lafferc
источник
источник
Ответы:
Использование
dis
для просмотра байт-кода, сгенерированного для двух версий:not ==
!=
Последний имеет меньше операций, и поэтому, вероятно, будет немного более эффективным.
Было отмечено, в commments (спасибо, @Quincunx ) , что если у вас есть
if foo != bar
противif not foo == bar
количество операций точно так же, это только то , чтоCOMPARE_OP
изменения иPOP_JUMP_IF_TRUE
переключается вPOP_JUMP_IF_FALSE
:not ==
:!=
В этом случае, если нет разницы в объеме работы, требуемой для каждого сравнения, маловероятно, что вы увидите какую-либо разницу в производительности вообще.
Тем не менее, обратите внимание, что две версии не всегда будут логически идентичны , так как это будет зависеть от реализаций
__eq__
и__ne__
для рассматриваемых объектов. Согласно документации модели данных :Например:
Наконец, и , возможно , самое главное: в общем, где два являются логически идентичны,
x != y
гораздо более удобным для чтения , чемnot x == y
.источник
__eq__
несоответствие__ne__
, полностью разрушен.not x == y
есть еще одна инструкция. Когда я поместил код в anif
, оказалось, что у них обоих одинаковое количество инструкций, только у однойPOP_JUMP_IF_TRUE
и другойPOP_JUMP_IF_FALSE
(это было единственное различие между ними, кроме использования разныхCOMPARE_OP
). Когда я скомпилировал код безif
s, я получил то, что вы получили.==
и!=
не являются взаимоисключающими, является SQL-подобная реализация, включающаяnull
значения. В SQLnull
не возвращаетсяtrue
по!=
сравнению с любым другим значением, поэтому реализации Python интерфейсов SQL также могут иметь такую же проблему.not ==
и!=
, похоже, это самая интересная часть моего ответа! Я не думаю, что это место, на котором стоит останавливаться, если, почему и когда это имеет смысл - см., Например, Почему в Python есть__ne__
метод оператора, а не просто__eq__
?У @jonrsharpe есть отличное объяснение того, что происходит. Я думал, что просто покажу разницу во времени при запуске каждого из 3 вариантов 10 000 000 раз (достаточно, чтобы показать небольшую разницу).
Используемый код:
И результаты профилировщика cProfile:
Итак, мы можем видеть, что есть очень маленькая разница в ~ 0,7% между
if not x == 'val':
иif x != 'val':
. Из нихif x != 'val':
самый быстрый.Однако, что самое удивительное, мы видим, что
на самом деле самый быстрый и бьет
if x != 'val':
на ~ 0,3%. Это не очень читабельно, но, думаю, если вы хотите незначительного улучшения производительности, можно пойти по этому пути.источник
В первом случае Python должен выполнить на одну операцию больше, чем необходимо (вместо того, чтобы просто проверять, что он не равен, он должен проверять, не является ли он истинным, что он равен, то есть еще одну операцию) Было бы невозможно отличить одно выполнение от другого, но если его запускать много раз, второе будет более эффективным. В целом я бы использовал второй, но математически они одинаковы
источник
Здесь вы можете увидеть, что
not x == y
есть еще одна инструкция, чемx != y
. Таким образом, разница в производительности будет очень мала в большинстве случаев, если вы не проводите миллионы сравнений, и даже тогда это, скорее всего, не станет причиной узкого места.источник
Дополнительное замечание, поскольку другие ответы в основном правильно ответили на ваш вопрос: если класс только определяет,
__eq__()
а что нет__ne__()
, то выCOMPARE_OP (!=)
его запустите__eq__()
и отрицаете. В то время ваш третий вариант, вероятно, будет чуть более эффективным, но его следует рассматривать только в том случае, если вам НУЖНА скорость, поскольку его сложно понять быстро.источник
Это о том, как ты это читаешь.
not
Оператор динамический, поэтому вы можете применить его вНо
!=
может быть прочитан в лучшем контексте как оператор, который делает противоположное тому, что==
делает.источник
not
оператор динамический" ?Я хочу расширить мой комментарий читабельности выше.
Опять же, я полностью согласен с тем, что читаемость перекрывает другие (незначительные по производительности) проблемы.
Я хотел бы отметить, что мозг интерпретирует «положительное» быстрее, чем «отрицательное». Например, «стоп» против «не уходи» (довольно паршивый пример из-за разницы в количестве слов).
Итак, дан выбор:
предпочтительнее функционально-эквивалентного:
Меньшая читаемость / понятность приводит к большему количеству ошибок. Возможно, не в первоначальном кодировании, но (не так умно, как вы!) Изменения в обслуживании ...
источник