Dlaczego === szybciej niż == w PHP?

168

Dlaczego jest ===szybszy niż ==w PHP?

coderex
źródło
40
Jest szybszy, ale czy znacznie szybszy?
Piskvor opuścił budynek
19
Proszę nie czytać o tym, co jest szybsze w php. Przeczytaj o tym, jak uzyskać interesujące dane w pojedynczym zapytaniu SQL bez nadużywania JOIN.
Kamil Szot
15
Dla kogo może być zainteresowany tym samym tematem === vs ==, ale w JAVASCRIPT, można przeczytać tutaj: stackoverflow.com/questions/359494/ ...
Marco Demaio
5
@Piskvor, to nie jest pytanie
Pacerier,
6
@Pacerier: Słuszna uwaga - dlatego tylko to skomentowałem. Nie odpowiada na pytanie, ale przedstawia perspektywę.
Piskvor opuścił budynek

Odpowiedzi:

200

Ponieważ operator równości ==wymusza lub konwertuje typ danych tymczasowo, aby sprawdzić, czy jest równy innemu operandowi, podczas gdy ===(operator tożsamości) nie musi wykonywać żadnej konwersji, a zatem wykonuje się mniej pracy, co czyni go szybszym.

meder omuraliev
źródło
Myślę, że twoja opinia jest sprzeczna z tym, co mówi Podręcznik PHP. Mówią, że $ a == $ b jest PRAWDZIWE, jeśli $ a jest równe $ b, gdzie $ a === $ b jest PRAWDA, jeśli $ a jest równe $ b i są tego samego typu.
Bakhtiyor
92
Jak więc jest inaczej?
meder omuraliev
2
Wydaje mi się, że w rzeczywistości 2 operandy wskazują na ten sam obszar pamięci dla typów złożonych, ale odpowiedź medera obejmuje to
Podstawowy
1
Ma to sens (tak jak w JS), ale fajnie by było, gdyby ktoś dodał też odniesienie do jakichś naprawdę prostych testów wydajnościowych.
Marco Demaio
4
phpbench.com wskazuje różnicę w wydajności między == i === w sekcji „Struktury sterowania”.
ekillaby
54

===nie wykonuje rzutowania, więc 0 == '0'oblicza do true, ale 0 === '0'- do false.

raveren
źródło
25

Po pierwsze, === sprawdza, czy dwa argumenty są tego samego typu - więc liczba 1 i ciąg „1” nie sprawdzają typu, zanim jakiekolwiek porównania zostaną faktycznie przeprowadzone. Z drugiej strony == nie sprawdza najpierw typu i przechodzi dalej i konwertuje oba argumenty na ten sam typ, a następnie wykonuje porównanie.

Dlatego === szybciej sprawdza warunek niepowodzenia

iblamefish
źródło
8
Domyślam się, że ==najpierw sprawdza również typ, aby sprawdzić, czy należy wykonać jakąkolwiek konwersję typów. Fakt, że ===w następnym kroku nie wykonuje żadnej konwersji, sprawia, że ​​jest ona szybsza.
deceze
25

Należy wziąć pod uwagę dwie kwestie:

  1. Jeśli są różne typy argumentów operacji wtedy ==i ===produkować różne wyniki . W takim przypadku prędkość operatorów nie ma znaczenia; liczy się, który z nich daje pożądany rezultat.

  2. Jeśli typy operandów są takie same, możesz użyć jednego ==lub ===obu, ponieważ dadzą te same wyniki . W takim przypadku prędkość obu operatorów jest prawie identyczna. Dzieje się tak, ponieważ żaden z operatorów nie przeprowadza konwersji typu.

Porównałem prędkość:

  • $a == $b vs $a === $b
  • gdzie $ai $bbyły losowymi liczbami całkowitymi [1, 100]
  • dwie zmienne zostały wygenerowane i porównane milion razy
  • testy przeprowadzono 10 razy

A oto wyniki:

 $a == $b $a === $b
--------- ---------
 0.765770  0.762020
 0.753041  0.825965
 0.770631  0.783696
 0.787824  0.781129
 0.757506  0.796142
 0.773537  0.796734
 0.768171  0.767894
 0.747850  0.777244
 0.836462  0.826406
 0.759361  0.773971
--------- ---------
 0.772015  0.789120

Widać, że prędkość jest prawie identyczna.

Salman A
źródło
13
Zastanawiam się, co się stanie, jeśli wykonasz kilka miliardów iteracji na maszynie, która nie robi nic innego i po prostu podaje średnią. wygląda na to, że jest tu sporo hałasu. ;)
Gung Foo,
4
Doszedłem do tego samego wniosku: nie można było zmylić żadnej różnicy, jeśli wiadomo, że operandy są tego samego typu. Inne scenariusze nie mają sensu. Prawie wszystkie inne odpowiedzi są po prostu błędne.
Paul Spiegel
1
Uważam, że to powinna być wybrana odpowiedź. Nie tylko racjonalizuje się to przypuszczeniami, założenia zostały bardziej lub mniej przetestowane empirycznie.
Pedro Amaral Couto
@PedroAmaralCouto Nie sądzę, ponieważ 10 nie jest badaniem empirycznym. Głównym powodem, dla którego nie ma prawie żadnej różnicy, jest to, że kompilator PHP prawdopodobnie zoptymalizuje kod. Należy używać ===, chyba że konwersja typu jest potrzebna, pomoże to zredukować błąd semantyczny (nawet jeśli występuje raz w całym życiu). Pomaga również kolejnej osobie czytającej kod, jakie zasady są egzekwowane. Piszesz raz, czytasz kilkaset razy, jeśli pomoże to wyjaśnić wątpliwości jednej osoby, to już się udało. Również brak testu pamięci, jeśli jest empiryczny, ponieważ sklonowano do tego samego typu. Jest więcej zasobów niż tylko czas.
Marco
@Marco, kiedy mówię „badanie empiryczne”, mam na myśli to, że opiera się na doświadczeniu, np .: uruchamianie kodu zamiast argumentowania, używając tylko powodu (lub tego, co masz na myśli), bez eksperymentu, aby go poprzeć. Wartości Salmana A sugerują, że === jest równie czasami nieco szybsze, a czasami nieco wolniejsze. Oznacza to "Dlaczego === szybszy niż == w PHP?" nasuwa pytanie: „Skąd wiesz, że === jest szybsze niż ==”? Optymalizacje kompilatora to wyjaśnienie, a nie to, co jest szybsze lub wolniejsze i nie powiedziałem, czego należy użyć.
Pedro Amaral Couto
7

Naprawdę nie wiem, czy jest to znacznie szybsze, ale === w większości języków jest bezpośrednim porównaniem typów, podczas gdy == spróbuje użyć przymusu typu, jeśli to konieczne / możliwe, aby uzyskać dopasowanie.

Chris
źródło
9
Javascript ma operator ===.
Frank Shearar
Jestem pewien, że możesz zrobić === w zwykłym seplenieniu i schemacie.
pupeno
Javascript - nie w 3 językach, które sprawdziłem;) A Lisp i Scheme to wiele rzeczy, ale rzadko spotykane;)
TomTom
1
ruby ma ===. Za długo nie pamiętałem, czy robi to samo.
KitsuneYMG
1
Ponadto, liveocs.adobe.com/flash/9.0/ActionScriptLangRefV3/… w przypadku skryptów akcji . Zasadniczo, Google „ścisła równość”.
Chris
4

== powoduje większy koszt konwersji typu przed porównaniem. === najpierw sprawdza typ, a następnie kontynuuje bez konieczności wykonywania jakiejkolwiek konwersji typu.

Jaskółka oknówka
źródło
3

Podsumowując, === jest szybsze, ponieważ nie konwertuje typu danych, aby zobaczyć, czy dwie zmienne mają tę samą wartość, ale kiedy chcesz sprawdzić, czy dwie zmienne mają tę samą wartość, użyjesz == jeśli nie ma znaczenia, jakiego typu są zmienne lub === jeśli ważny jest również typ zmiennych.

D.Martin
źródło
0

Szybsze nie powinno być mierzone tylko w bezpośrednim czasie wykonania (bezpośrednie testy wydajności są w tym przypadku prawie pomijalne). To powiedziawszy, musiałbym zobaczyć test obejmujący iterację lub rekurencję, aby naprawdę zobaczyć, czy istnieje znacząca, skumulowana różnica (w przypadku użycia w realistycznym kontekście). Znaczący powinien być również czas testowania i debugowania, który zaoszczędzisz podczas zajmowania się skrajnymi przypadkami

Anthony Rutledge
źródło
0

W php (kod c) wartością jest „klasa”, na przykład:

class value
{
    $int_;
    $float_;
    $string_;
    $array_;
    $object_;
}

Kiedy Twój porównujesz $a == $bi $ajest inttypu, nie będzie coś takiego:

if ($a->int_ == $b->int_ || $a->int_ == (int) $b->float_ || $a->int_ == (int) $b->string_ || ...)

ale string '1'nie będzie rzutowany na kod ascii 49, będzie 1.

Kiedy porównujesz $a === $bi $ajest inttypu, nie będzie cos takiego jak:

if ($a->int_ == $b->int_)
d0niek
źródło
-4

Jeśli wyniki testu są prawidłowe, to musi to być problem kompilatora,

Procesor zrobi wszystko, co mu każą w cyklu zegara

Jeśli ma mniej do zrobienia, będzie to szybsze

Dodanie:

No cóż, właściwie, jeśli kompilator utworzył już mnóstwo kodu maszynowego do przetworzenia, to jeśli dodał już miliardy rzeczy, aby poradzić sobie z typem danych, które wymagają porównania, to usunięcie jednego "pomniejszego" IF nie zmieni znacznie prędkości w ogóle.

Jeśli ktoś jeszcze to czyta, jestem zainteresowany dalszą dyskusją.

Phil

Phil Allen
źródło
Czy masz tylko „jedną” instrukcję IF w swoim kodzie? To dziwne, ponieważ w każdej bazie kodu, nad którą pracowałem, mamy tysiące instrukcji IF lub porównawczych wywoływanych wszędzie.
Lew