JavaScript performance difference between double equals (==) and triple equals (===)

16,445

Solution 1

Strict comparison (===) will always be slightly faster, but the difference is usually negligible.

It definitely makes sense to prefer === if you know for certain that you don't need type coercion in the comparison. It will always be at least as fast as ==.

Solution 2

  • If the types compared are the same, they are identical. That is to say they use the exact same algorithm.

  • If the types are different, then performance is irrelevant. Either you need type coercion, or you don't. If you don't need it, don't use == because the result you get may be unexpected.

Solution 3

Edit: for reference here's the by the spec explanation by Dr. Axel Rauschmayer http://www.2ality.com/2011/06/javascript-equality.html Really great write up.

=== (Strict Equality): Only considers values equal that have the same type.

  1. undefined === undefined, null === null,
  2. NaN === nothing including itself,
  3. Primitive [Number|String|Boolean] === primitive value equal,
  4. to self (+0 === -0)
  5. Two objects [Array|Object|Function] === Only self (same exact entity)

== (Lenient Equality)

  1. If both values have the same type: compare with ===.
  2. undefined == null
  3. number and string: string => number and compare
  4. boolean and non-boolean => non-boolean to number and compare
  5. string or number => an object: convert object to primitive and comparison.

In all modern Javascript environments they are implemented completely different. In simple terms, == tests for alikeness via converting given variables into primitives (string, number, boolean). === tests for strict sameness, which means exact same Object or primitive value without conversion.

If you do objOne == objTwo what actually happens is [[EQUALS]].call(objOne.valueOf(), objTwo.valueOf())

The resolution of valueOf can be somewhat involved, bouncing between functions exposed in JS and internal engine stuff. Suffice to say that the comparison will always end up with two values coerced to primitive or an error will be thrown.

Edit: EQUALS actually tries STRICT_EQUALS first which preempts the rest of the process.

The interesting bit here is that valueOf (and its partner toString) are overridable. Run this piece of code in Chrome (I think any webkit, not sure if JSC and V8 share this tidbit). It will blow your 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);

Output:

[ { 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 } ]

The essence of the difference between == and === is illustrated by === not showing up in that list. It skips the journey into JavascriptLand entirely. That adventure is expensive when comparing performance.

However you need to account for engine optimizations. For most objects, the engine will be able to cut out most of the steps and stay in NativeLand and get almost the same performance. But this isn't a guarantee and if something prevents the engine from being able to use the optimizations, some fancyness in your code or overriding the builtins or a myriad of issues, then you instantly see the result in performance. === forces it.

=== is just about the only immutable thing in Javascript.

Solution 4

Due to performance, I think === has better performance, because === is stricter than ==,

e.g. try the following in the Chrome console.

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

== has to check more things than ===

Solution 5

From some flimsy tests, == appears to be marginally quicker than ===.

By marginally, I mean that I can see a few milliseconds difference on interations of many millions of tests. You can't possibly need the performance gain, rather than using whatever is most correct for the task at hand.

EDIT: actually, seems to depend on /what/ you're comparing and the browser implementation. In other words, don't worry about it.

Share:
16,445

Related videos on Youtube

Eric
Author by

Eric

Full stack software engineer specializing in creating usable web applications, UX, Performance, and Infrastructure.

Updated on June 19, 2022

Comments

  • Eric
    Eric almost 2 years

    In JavaScript, is there a performance difference between using a double equals (==) vs using a triple equals (===)?

    Example: if (foo == bar) vs if (foo === bar)

    • Lightness Races in Orbit
      Lightness Races in Orbit over 12 years
      Nothing you'll ever, ever notice. Move on.
    • user229044
      user229044 over 12 years
      They serve different purposes, and "more performance" isn't one of them. It's a non-issue, use them when you want to obtain the functionality they provide.
    • Jon Surrell
      Jon Surrell almost 9 years
      Recommended reading: You don't know JS
    • GreenRaccoon23
      GreenRaccoon23 over 8 years
      Since this is still the top Google result for this question and I don't see any test results, I'll add one. The average results of a little Node.js test, run 4 times (80,000,000,000 total tests for each of the 2 operators), found === 0.0027% faster than ==. The difference, if it's really even that high, is about 10,000 times faster than the blink of an eye or the time for the average human brain to react to the average stimulus. To support Lightness Races in Orbit's comment, I can't think of a scenario where it'd ever be humanly possible to notice a speed difference between the two.
    • massic80
      massic80 about 4 years
      @JonSurrell thanks for the interesting link :) Five years later, the address has changed
    • Jon Surrell
      Jon Surrell over 3 years
      Updated recommended reading link: You Don't Know JS
  • Nightfirecat
    Nightfirecat over 12 years
    Funny, because == beat === for me, in both times I ran the test, on FF7. I'd agree that === ought to be faster, but the test claims otherwise. (probably discrepancy in the Javascript engine/CPU load, who knows)
  • rlorenzo
    rlorenzo over 12 years
    @Nightfirecat: That's interesting. Were you comparing variables or literals?
  • Raynos
    Raynos over 12 years
    === is faster in most cases. There are edge cases (you found one). However from a code practice/style guide === wins hands down every time
  • Nightfirecat
    Nightfirecat over 12 years
    I was just using the default tests it used - namely the "==/=== on same type only" tests, as those were the fastest of any of them. I believe the same pattern showed up in all of the by-type comparison as opposed to the regular comparison tests, don't remember.
  • Tim Down
    Tim Down over 12 years
    If the operands are of the same type then == and === are specified to perform precisely the same steps.
  • Tim Down
    Tim Down over 12 years
    Where's your evidence for this? Since == and === are specified to work precisely the same when the operands are of the same type, I can't believe JS environments would implement them differently in that case.
  • Admin
    Admin over 12 years
    ....did you read any of my post after the first sentence? I literally included V8 output. Short answer: == calls === first and in cases where === is true the difference is negligible. Beyond that == has to lose by definition.
  • Admin
    Admin over 12 years
    And just to note for posterity. My above evidence is a novel method I came up with that is able to identify internal JS engine operator function callers and the operands correctly positioned, from arbitrary JavaScript objects, in all current implementations using V8 or JavaScriptCore, which I've never seen elsewhere, and which directly enables operator overloading in JS which is otherwise impossible and currently not successfully implemented otherwise.
  • Tim Down
    Tim Down over 12 years
    I read it. Sorry, I should have been more specific about what evidence was missing: the part about "all modern Javascript environments". The internals of V8 that are exposed are interesting, but valueOf() has been around since ECMAScript 1 in 1997, so is hardly novel. You haven't addressed my point, which is the question of what happens when the two operands are of the same type. Add operator == {} and operator === {} to your example and you'll see that neither of them show up in your actions array.
  • Brian Arsuaga
    Brian Arsuaga almost 11 years
    This should really have been the answer, imo. == calls === then attempts coercion to see if it's alike in some other way. === is obviously faster, then, for unequal objects when you are trying to compare identities.
  • Tim Down
    Tim Down over 10 years
    @BrianArsuaga: === is only faster if the objects are of different types.
  • cdosborn
    cdosborn over 8 years
    "don't worry about it", "You can't possibly need the performance gain". You don't know the intentions of this user, and all users that come here for this question.
  • Hamish
    Hamish over 8 years
    @cdosborn woah, hello 2011. This Q pre-dates the nodejs tag on SO. Yes, you are correct. At the time it was a fair assumption that this was in the browser, and shaving milliseconds/millions of evaluations would be.. a bad use of your time. Things have changed a LOT in ~5 years.
  • Nico Haase
    Nico Haase about 5 years
    Do you have any sources for that comparison? The other answers mention that the difference is negliglible
  • Joseph C
    Joseph C about 5 years
    performance wise the difference is essentially negligible, but it still exists
  • Nico Haase
    Nico Haase about 5 years
    Please explain that further - why does it exist? How negligible is it really? It’s preferred to write answers based on facts, such that others can learn from them
  • Kiwi Rupela
    Kiwi Rupela about 5 years
    console.time("test") 2 === 2 console.timeEnd("test") VM137:3 test: 0.006103515625ms console.time("test1") 2 == 2 console.timeEnd("test1") VM147:3 test1: 0.0048828125ms I know === is slightly faster how can i test this why i am getting reverse result is my approach is wrong?
  • Ofir Meguri
    Ofir Meguri over 4 years
    why do you say it is slightly faster. According to your jsperf link it is x10 faster when it is not the same type
  • Drakinite
    Drakinite about 3 years
    If the types are different, then == may be significantly slower. For example: x = ''; y = 0; (x == y) performs typecasting, which causes slowdowns. If you know that the types may be different, and you are super concerned with performance, then using === might give a bit faster. (But if you do typecasting yourself, then there won't be a performance improvement, obviously.)