2015-08-13 10 views
7

Podsumowując, zrobiłem pętlę z kilku iteracji, aby sprawdzić skuteczność każdego testu:Dlaczego funkcja isset() jest bardziej wydajna niż "==="?

$iterations = 99999999; 
$var = null; 

isset comparasion

if (isset($var)) 
    { 

    } 

'===' comparasion

if ($var === null) 
    { 

    } 

I Mam ten dziennik w mikrosekundach:

'isset()': 1.4792940616608 
'===': 1.9428749084473 

Dla mnie to trochę dziwne. Dlaczego funkcja isset() jest szybsza niż jeden operator porównania jako ===?

+7

'Isset' nie jest funkcją: jest językiem wbudowanym. Użycie 'isset' jest szybsze niż użycie funkcji. Inną rzeczą jest to, że 'isset' jest używany wszędzie, więc ma sens, że został profilowany na śmierć, podczas gdy' === 'może nie otrzymał tyle miłości. – zneak

+2

Co ciekawe, "isset" służy do sprawdzenia, czy zmienna jest w ogóle ORAZ jeśli nie jest zerowa, podczas gdy operator "===" jest używany do sprawdzenia, czy te dwie wartości są identyczne, czy nie. Można by pomyśleć, że "isset" będzie wolniejszy o kilka milisekund z powodu sprawdzenia dwóch rzeczy, gdzie "===" tylko sprawdza jeden. –

+0

'isset()' jest po prostu ustawiona zmienna sprawdzająca, czy nie. natomiast '===' porównaj wartość. Właśnie dlatego funkcja isset jest bardziej wydajna niż "==="; Myślę, że obie są różnymi rzeczami. Używamy obu do tej samej funkcji. –

Odpowiedz

4

Porównanie jest ścisłym sprawdzianem, co oznacza, że ​​oba porównywane obiekty muszą być tego samego typu. Kiedy rozbicie go na zwykły angielski, to wcale nie jest dziwne, że potrzebuje więcej czasu. Rozważmy parser, aby to zrobić:

if (isset($var)) { 
    // Do I have something called $var stored in memory? 
    // Why yes, I do.. good, return true! 
} 

if ($var === null) { 
    // Do I have something called $var stored in memory? 
    // Why yes, I do.. good! But is it a NULL type? 
    // Yes, it is! Good, return true! 
} 

Jak widać, operator === musi wykonać dodatkowe sprawdzenie, zanim będzie mogła określić, czy zmienna odpowiada stan, więc nie jest to dziwne, że to jest trochę wolniej.

+3

'isset' również wykonuje porównanie z' null'. Twoje wyjaśnienie jest trochę nienaukowe. – zerkms

+2

Dałem to +1, ponieważ robi to właściwy punkt, chociaż zgadzam się również z punktem @zerkms. Warto również wskazać OP, że choć jedna operacja może być szybsza niż następna, żadna z nich nie może być uważana za powolną; uważaj na pokusę, by zbytnio analizować takie rzeczy i robić mikrooptymalizację, ponieważ bardzo rzadko ma to znaczący wpływ na wydajność twojego kodu. Jeśli chcesz zoptymalizować swój kod, najpierw dowiedz się, gdzie znajdują się wąskie gardła, i staraj się zoptymalizować te fragmenty. – Simba

+0

@zerkms To prawda, nie mam na myśli, że to dowód naukowy. To tylko przykład, aby zademonstrować, że '===' musi wykonać dodatkowe kroki, zanim dojdzie do ostatecznego wniosku. – Oldskool

1

Isset nie jest funkcją: jest językiem wbudowanym. Korzystanie z isset jest szybsze niż korzystanie z funkcji.

Drugą sprawą jest to, że ten zestaw jest używany w każdym miejscu, więc ma sens, że został profilowany na śmierć, podczas gdy === może nie otrzymał tyle miłości.

Poza tym, musisz wykopać źródło PHP za pomocą profilera, aby zobaczyć dokładnie, co się dzieje.

0

Nie jestem pewien, czy nazwałbym 100 milionów "kilkoma iteracjami". Wygląda na to, że nagromadziłeś około półsekundową różnicę, podziel ją przez 100 milionów, a otrzymasz silną 5 nanosekundową różnicę na iterację, jeśli moja matematyka jest poprawna. Ponieważ różnica jest tak mała, może po prostu sprowadzić się do tego, że isset ma tylko jeden argument w tym kontekście, a === ma dwa.

Nie można nawet omówić szczegółów implementacji silnika Zend tych dwóch przykładów bez określenia konkretnej wersji PHP; kod źródłowy to ruchomy cel. Nawet niewielkie zmiany w implementacjach mają wpływ na wyniki w ciągu wielu przejść. Nie zdziwiłbym się, gdyby okazało się, że jest inaczej w niektórych wersjach PHP i/lub w innym kontekście.

isset sama jest objęta trzema różnymi op-kodów w VM, w zależności od kontekstu:

"Simple" Opracowanie zmiennych takich jak Twój przykład: ZEND_ISSET_ISEMPTY_VAR

Tablice: ZEND_ISSET_ISEMPTY_DIM_OBJ (wymaga 2 argumenty, Var a wskaźnik)

właściwości obiektu: ZEND_ISSET_ISEMPTY_PROP_OBJ (również 2 argumenty, var prop nAME)

jest interesujące pytanie Cu na szczęście, ale dzielimy się włosami i prawdopodobnie nie jest to prawdziwa strategia optymalizacji.

+0

Inne rzeczy mogą ulec zmianie w zależności od kontekstu. Sprawdzanie 'if ($ var === 'foo')' prawdopodobnie będzie odrobinę szybsze niż w przykładzie, ponieważ implementacja pod maską może wcześniej wyjść z 'false' w momencie, gdy widzi, że dwa operandy nie są takie same rodzaj. –

Powiązane problemy