2011-11-08 6 views
32

Czy w JavaScript występuje różnica w wydajności między używaniem podwójnej równości (==) a używaniem potrójnej równości (===)?Różnica w wydajności JavaScript między podwójnymi równymi (==) i potrójnymi równymi (===)

przykład: if (foo == bar) vs if (foo === bar)

+20

Nic, co kiedykolwiek zauważysz. Pójść dalej. –

+2

Służą one do różnych celów, a "większa wydajność" nie należy do nich. To nie jest problem, użyj ich, jeśli chcesz uzyskać dostępną funkcjonalność. – meagar

+0

Zalecane uwagi: [Nie wiesz, JS] (https://github.com/getify/You-Dont-Know-JS/blob/master/types%20&%20grammar/ch4.md#loose-equals-vs -strict-equals) –

Odpowiedz

25

Strict porównanie (===) zawsze będzie nieco szybciej, ale the difference is usually negligible.

Zdecydowanie warto wybrać ===, jeśli wiadomo na pewno, że w porównaniu nie trzeba stosować przymusu. Zawsze będzie co najmniej tak szybki jak ==.

+3

Zabawne, ponieważ '==' pobić '===' dla mnie, w obu przypadkach przeprowadziłem test, na FF7. Zgadzam się, że '===' powinno być szybsze, ale test twierdzi inaczej. (prawdopodobnie rozbieżność w obciążeniu silnika JavaScript/CPU, kto wie) – Nightfirecat

+0

@Nightfirecat: To interesujące. Czy porównywałeś zmienne lub literały? –

+0

Używałem tylko testów domyślnych, których używał - a mianowicie testów "==/=== na samych tylko typach", ponieważ były to najszybsze z nich. Uważam, że ten sam schemat pojawił się we wszystkich porównaniach typu, w przeciwieństwie do zwykłych testów porównawczych, nie pamiętam. – Nightfirecat

3

Ze względu na wydajność, myślę === ma lepszą wydajność, ponieważ === są bardziej restrykcyjne niż ==,

np spróbuj poniższych rozwiązań w konsoli Chrome.

> 1 == '1' 
    true 
> 1 === '1' 
    false 

== musi sprawdzić więcej rzeczy niż ===

1

Z niektórych marnych testów, == wydaje się być nieznacznie szybsza niż ===.

Mam na myśli, że widzę kilka milisekund różnicy na interakcje wielu milionów testów. Prawdopodobnie nie potrzebujesz przyrostu wydajności, zamiast używać tego, co jest najbardziej poprawne dla danego zadania.

EDYCJA: faktycznie, wydaje się zależeć od/what/you're porównania i implementacji przeglądarki. Innymi słowy, nie przejmuj się tym.

+1

'===' jest szybszy w większości przypadków. Są przypadki krańcowe (znalazłeś je). Jednak z przewodnika po ćwiczeniach/stylach '===' wygrywa rozdanie za każdym razem, – Raynos

+2

"nie martw się o to", "Nie możesz prawdopodobnie potrzebować przyrostu wydajności". Nie znasz intencji tego użytkownika i wszystkich użytkowników, którzy przychodzą tutaj w celu uzyskania tego pytania. – cdosborn

+2

@cdosborn woah, hello 2011. To Q pre-datuje tag nodejs na SO. Tak, masz rację. W tamtym czasie było jasne założenie, że to jest w przeglądarce, a golenie milisekund/miliony ocen byłoby ... złym wykorzystaniem twojego czasu. Rzeczy zmieniły się w LOT za około 5 lat. – Hamish

38
  • Jeśli typy porównywane są takie same, są one identyczne. To znaczy, że używają dokładnie tego samego algorytmu.

  • Jeśli typy są różne, wydajność nie ma znaczenia. Albo potrzebujesz przymusu, albo nie. Jeśli go nie potrzebujesz, nie używaj ==, ponieważ otrzymany wynik może być nieoczekiwany.

14

Edit: odsyłające oto przez Spec wyjaśnienia dr Axel Rauschmayer http://www.2ality.com/2011/06/javascript-equality.html naprawdę wielki napisać.

=== (Ścisła równość): uwzględnia tylko wartości równe temu samemu typowi.

  1. niezdefiniowany === niezdefiniowany, null === null,
  2. NaN === nic się w tym,
  3. Primitive [Number | String | Boolean] === wartość prymitywny równe,
  4. do siebie (+0 === -0)
  5. dwa obiekty [Array | Przedmiot | Funkcja] === Tylko samo (dokładnie taki sam podmiot)

== (Åagodne Równość)

  1. Jeśli obie wartości mają ten sam typ: porównaj z ===.
  2. niezdefiniowany == null
  3. liczba i ciąg: string => liczba i porównać
  4. logiczną i non-Boolean => non-logiczną do liczby i porównać
  5. ciąg lub numer => obiekt: konwertować obiekt do prymitywizmu i porównania.

We wszystkich nowoczesnych środowiskach Javascript są one implementowane zupełnie inaczej. W prostych słowach, testy == dla podobieństwa poprzez konwersję danych zmiennych na prymitywy (string, number, boolean). === testuje ścisłą identyczność, co oznacza dokładnie ten sam obiekt lub prymitywną wartość bez konwersji.

Jeśli nie objOne == objTwo co faktycznie dzieje [[EQUALS]].call(objOne.valueOf(), objTwo.valueOf())

Rozdzielczość valueOf może być nieco zaangażowane, odbijając się od funkcji narażonych w JS i wewnętrznej rzeczy silnika. Wystarczy powiedzieć, że porównanie zawsze kończy się na dwóch wartościach wymuszonych na prymitywne lub zostanie zgłoszony błąd.

Edytuj:EQUALS najpierw próbuje STRICT_EQUALS, co uprzedza resztę procesu.

Interesujące jest to, że valueOf (i jego partner doString) są overridable. Uruchom ten fragment kodu w Chrome (chyba każdy webkit, nie wiem, czy JSC i V8 dzielą tę ciekawość). Będzie to cios mindpiece:

var actions = []; 
var overload = { 
    valueOf: function(){ 
    var caller = arguments.callee.caller; 
    actions.push({ 
     operation: caller.name, 
     left: caller.arguments[0] === this ? "unknown" : this, 
     right: caller.arguments[0] 
    }); 
    return Object.prototype.toString.call(this); 
    } 
}; 
overload.toString = overload.valueOf; 
overload == 10; 
overload === 10; 
overload * 10; 
10/overload; 
overload in window; 
-overload; 
+overload; 
overload < 5; 
overload > 5; 
[][overload]; 
overload == overload; 
console.log(actions); 

wyjściowa:

[ { operation: 'EQUALS', 
    left: overload, 
    right: 10 }, 
    { operation: 'MUL', 
    left: overload, 
    right: 10 }, 
    { operation: 'DIV', 
    left: 'unknown', 
    right: overload }, 
    { operation: 'IN', 
    left: overload, 
    right: DOMWindow }, 
    { operation: 'UNARY_MINUS', 
    left: overload, 
    right: undefined }, 
    { operation: 'TO_NUMBER', 
    left: overload, 
    right: undefined }, 
    { operation: 'COMPARE', 
    left: overload, 
    right: 5 }, 
    { operation: 'COMPARE', 
    left: 'unknown', 
    right: overload }, 
    { operation: 'ToString', 
    left: 'unknown', 
    right: overload } ] 

Istota różnicy między == i === ilustrują === nie znalazły się na tej liście. Pomija całkowicie podróż do JavascriptLand. Ta przygoda jest kosztowna przy porównywaniu wydajności.

Należy jednak uwzględnić optymalizacje silnika. W przypadku większości obiektów silnik będzie w stanie odciąć większość kroków i pozostać w NativeLand i uzyskać prawie taką samą wydajność. Ale to nie jest gwarancja i jeśli coś uniemożliwia silnikowi korzystanie z optymalizacji, jakąś fantazję w kodzie lub nadpisywanie wbudowanych lub mnóstwo problemów, natychmiast widzisz wynik w wydajności. === zmusza go.

=== jest prawie jedyną niezmienną rzeczą w JavaScript.

+0

Gdzie są twoje dowody na to? Ponieważ '==' i '===' są określone dokładnie tak samo, gdy operandy są tego samego typu, nie mogę uwierzyć, że środowiska JS implementowałyby je inaczej w tym przypadku. –

+0

.... Czy przeczytałeś któryś z moich postów po pierwszym zdaniu? Dosłownie zawierałem wyjście V8. Krótka odpowiedź: == połączenia === pierwsza i w przypadkach, gdy === jest prawdą, różnica jest znikoma. Poza tym == musi z definicji stracić. –

+0

I tylko dla potomności. Moje powyższe dowody to nowatorska metoda, którą wymyśliłem, która jest w stanie zidentyfikować wewnętrznych wywoływaczy funkcji silnika JS i operandy poprawnie umieszczone, z dowolnych obiektów JavaScript, we wszystkich obecnych implementacjach przy użyciu V8 lub JavaScriptCore, których nigdy wcześniej nie widziałem, i która bezpośrednio umożliwia przeciążanie operatora w JS, co w przeciwnym razie jest niemożliwe i obecnie nie jest realizowane z powodzeniem w inny sposób. –