Jaka jest różnica między tymi dwoma wierszami kodu:
if not x == 'val':
i
if x != 'val':
Czy jedno jest bardziej wydajne od drugiego?
Czy lepiej byłoby użyć
if x == 'val':
pass
else:
python
if-statement
equality
Lafferc
źródło
źródło
Odpowiedzi:
Używając
dis
do przeglądania kodu bajtowego wygenerowanego dla dwóch wersji:not ==
!=
Ten ostatni ma mniej operacji i dlatego może być nieco bardziej wydajny.
W komisjach (dzięki, @Quincunx ) wskazano, że tam, gdzie masz,
if foo != bar
aif not foo == bar
liczba operacji jest dokładnie taka sama, po prostuCOMPARE_OP
zmiany i zmianaPOP_JUMP_IF_TRUE
naPOP_JUMP_IF_FALSE
:not ==
:!=
W takim przypadku, chyba że wystąpi różnica w ilości pracy wymaganej do każdego porównania, jest mało prawdopodobne, aby w ogóle dostrzegłaś różnicę w wydajności.
Należy jednak pamiętać, że dwie wersje nie zawsze będą logicznie identyczne , ponieważ będą zależeć od implementacji
__eq__
i__ne__
dla przedmiotowych obiektów. Według dokumentacji modelu danych :Na przykład:
Wreszcie, a być może najważniejsze: ogólnie rzecz biorąc, gdy oba są logicznie identyczne,
x != y
jest o wiele bardziej czytelny niżnot x == y
.źródło
__eq__
niespójna__ne__
jest zepsuta.not x == y
ma jeszcze jedną instrukcję. Kiedy wstawiłem kod doif
, okazało się, że oba mają tę samą liczbę instrukcji, tylko jedna z nichPOP_JUMP_IF_TRUE
i drugaPOP_JUMP_IF_FALSE
(to była jedyna różnica między nimi, inna niż użycie innejCOMPARE_OP
). Kiedy skompilowałem kod bezif
s, dostałem to, co masz.==
i!=
nie wykluczają się wzajemnie jest SQL-like wdrożeniowych obejmującychnull
wartości. W SQLnull
nie wracatrue
do!=
żadnej innej wartości, więc implementacje interfejsów SQL w Pythonie mogą mieć ten sam problem.not ==
i!=
wydaje się, że jest to najbardziej interesująca część mojej odpowiedzi! Nie sądzę, że jest to miejsce do zastanowienia się, czy, dlaczego i kiedy ma to sens - patrz np. Dlaczego Python ma__ne__
metodę operatora zamiast tylko__eq__
?@jonrsharpe ma doskonałe wyjaśnienie tego, co się dzieje. Pomyślałem, że pokażę różnicę czasu podczas uruchamiania każdej z 3 opcji 10 000 000 razy (wystarczy, aby pokazać niewielką różnicę).
Zastosowany kod:
A wyniki profilera cProfile:
Widzimy więc, że istnieje bardzo niewielka różnica ~ 0,7% między
if not x == 'val':
iif x != 'val':
. Spośród nichif x != 'val':
jest najszybszy.Co jednak najbardziej zaskakujące, widzimy to
jest w rzeczywistości najszybszy i bije
if x != 'val':
o ~ 0,3%. Nie jest to zbyt czytelne, ale myślę, że jeśli chcesz nieznacznej poprawy wydajności, możesz pójść tą drogą.źródło
W pierwszym Python musi wykonać jeszcze jedną operację więcej niż to konieczne (zamiast po prostu sprawdzić, że nie jest równy, musi sprawdzić, czy nie jest prawdą, że jest równy, a zatem jeszcze jedną operację). Niemożliwe byłoby odróżnienie od jednego wykonania, ale jeśli uruchomione wiele razy, drugie będzie bardziej wydajne. Ogólnie skorzystałbym z drugiego, ale matematycznie są takie same
źródło
Tutaj możesz zobaczyć, że
not x == y
ma jeszcze jedną instrukcję niżx != y
. Różnica w wydajności będzie w większości przypadków bardzo mała, chyba że wykonasz miliony porównań, a nawet wtedy prawdopodobnie nie będzie to przyczyną wąskiego gardła.źródło
Dodatkowa uwaga, ponieważ inne odpowiedzi odpowiedziały na twoje pytanie w większości poprawnie, jest to, że jeśli klasa tylko definiuje,
__eq__()
a nie__ne__()
, toCOMPARE_OP (!=)
będziesz biegał__eq__()
i negował to. W tym czasie trzecia opcja może być nieco bardziej wydajna, ale należy ją rozważyć tylko wtedy, gdy POTRZEBUJESZ prędkości, ponieważ trudno ją szybko zrozumieć.źródło
Chodzi o twój sposób czytania.
not
operator jest dynamiczny, dlatego możesz go zastosowaćAle
!=
może być odczytany w lepszym kontekście jako operator, który robi coś przeciwnego do tego, co==
robi.źródło
not
operator jest dynamiczny” ?Chcę rozwinąć mój komentarz dotyczący czytelności powyżej.
Ponownie całkowicie zgadzam się z czytelnością przesłaniającą inne problemy (nieznaczące w wydajności).
Chciałbym zwrócić uwagę, że mózg interpretuje „pozytywne” szybciej niż „negatywne”. Np. „Stop” vs. „nie idź” (raczej kiepski przykład z powodu różnicy w liczbie słów).
Tak więc wybór:
jest lepszy niż funkcjonalnie równoważny:
Mniejsza czytelność / zrozumiałość prowadzi do większej liczby błędów. Być może nie w początkowym kodowaniu, ale zmiany w konserwacji (nie tak mądre jak ty!) ...
źródło