双等号 (==) 和三等号 (===) 之间的 JavaScript 性能差异
Posted
技术标签:
【中文标题】双等号 (==) 和三等号 (===) 之间的 JavaScript 性能差异【英文标题】:JavaScript performance difference between double equals (==) and triple equals (===) 【发布时间】:2011-12-24 02:10:33 【问题描述】:在 javascript 中,使用双等号 (==
) 与使用三等号 (===
) 之间是否存在性能差异?
示例:if (foo == bar)
与 if (foo === bar)
【问题讨论】:
您永远不会注意到任何事情。继续前进。 它们有不同的用途,“更高的性能”不是其中之一。这不是问题,当您想获得它们提供的功能时使用它们。 推荐阅读:You don't know JS 由于这仍然是该问题的最高 Google 结果,并且我没有看到任何测试结果,所以我将添加一个。一个小 Node.js 测试的平均结果,运行 4 次(2 个操作符中的每一个总共测试 80,000,000,000 次),发现===
比 ==
快 0.0027%。差异,如果它真的那么高,大约比眨眼或人类大脑对平均刺激做出反应的时间快 10,000 倍。为了支持Lightness Races in Orbit
的评论,我想不出人类可能会注意到两者之间的速度差异的场景。
@JonSurrell 感谢您提供有趣的链接 :) 五年后,the address has changed
【参考方案1】:
如果比较的类型相同,它们是相同的。也就是说,他们使用完全相同的算法。
如果类型不同,则性能无关紧要。要么你需要类型强制,要么你不需要。如果您不需要它,请不要使用==
,因为您得到的结果可能会出乎意料。
【讨论】:
【参考方案2】:严格比较 (===
) 总是会稍微快一些,但 the difference is usually negligible。
如果您确定在比较中不需要类型强制,那么首选===
绝对是有意义的。它总是至少和==
一样快。
【讨论】:
很有趣,因为==
对我来说击败了===
,这两次我都在FF7 上进行了测试。我同意===
应该更快,但测试声称并非如此。 (可能是 Javascript 引擎/CPU 负载的差异,谁知道)
@Nightfirecat:这很有趣。你是在比较变量还是文字?
我只是使用它使用的默认测试——即“==/=== 仅在相同类型上”测试,因为这些测试是其中最快的。我相信与常规比较测试相反,所有按类型比较中都出现了相同的模式,不记得了。
如果操作数属于同一类型,则指定 ==
和 ===
以执行完全相同的步骤。
console.time("test") 2 === 2 console.timeEnd("test") VM137:3 test: 0.006103515625ms console.time("test1") 2 == 2 控制台。 timeEnd("test1") VM147:3 test1: 0.0048828125ms 我知道 === 稍快我如何测试这个为什么我得到相反的结果是我的方法是错误的?【参考方案3】:
编辑:供参考,这是 Axel Rauschmayer 博士的规范解释 http://www.2ality.com/2011/06/javascript-equality.html 写得真好。
===
(严格相等):仅考虑具有相同类型的相等值。
-
未定义 === 未定义,空 === 空,
NaN === 没有,包括它自己,
原始 [Number|String|Boolean] === 原始值相等,
对自己 (+0 === -0)
两个对象 [Array|Object|Function] === 只有自己(完全相同的实体)
==
(宽大平等)
-
如果两个值的类型相同:与 === 比较。
未定义 == 空
数字和字符串:字符串 => 数字和比较
boolean and non-boolean => non-boolean to number and compare
字符串或数字 => 对象:将对象转换为原始对象并进行比较。
在所有现代 Javascript 环境中,它们的实现方式完全不同。简单来说,==
通过将给定变量转换为原语(字符串、数字、布尔值)来测试相似性。 ===
测试严格相同,这意味着完全相同的 Object 或原始值,无需转换。
如果你这样做
objOne == objTwo
实际发生的是
[[EQUALS]].call(objOne.valueOf(), objTwo.valueOf())
valueOf 的解析可能有点牵扯,在 JS 中公开的函数和内部引擎的东西之间来回切换。可以说,比较总是会以两个强制为原始值的值结束,否则会引发错误。
编辑: EQUALS
实际上会先尝试 STRICT_EQUALS
,它会抢占进程的其余部分。
这里有趣的一点是 valueOf(及其伙伴 toString)是可覆盖的。在 Chrome 中运行这段代码(我认为任何 webkit,不确定 JSC 和 V8 是否共享这个花絮)。它会让你大吃一惊:
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);
输出:
[ 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 ]
==
和 ===
之间区别的本质是 ===
没有出现在该列表中。它完全跳过了进入 JavascriptLand 的旅程。比较性能时,这种冒险是昂贵的。
但是,您需要考虑引擎优化。对于大多数对象,引擎将能够减少大部分步骤并留在 NativeLand 中并获得几乎相同的性能。但这并不是保证,如果有什么东西阻止引擎使用优化、代码中的一些花哨或覆盖内置函数或无数问题,那么您会立即看到性能结果。 ===
强制它。
===
几乎是 Javascript 中唯一不可变的东西。
【讨论】:
你的证据在哪里?由于==
和 ===
被指定为在操作数属于同一类型时完全相同地工作,我无法相信 JS 环境在这种情况下会以不同的方式实现它们。
....你在第一句话之后读过我的任何帖子吗?我确实包含了 V8 输出。简短的回答: == 首先调用 === 并且在 === 为真的情况下,差异可以忽略不计。除此之外 == 根据定义必须输。
只是为了后代注意。我的上述证据是我想出的一种新方法,它能够在所有当前使用 V8 或 JavaScriptCore 的实现中,从任意 JavaScript 对象中识别内部 JS 引擎操作符函数调用者和正确定位的操作数,这是我在其他地方从未见过的,并且直接启用了 JS 中的运算符重载,否则这是不可能的,目前还没有成功实现。
我读过。抱歉,我应该更具体地说明缺少哪些证据:关于“所有现代 Javascript 环境”的部分。暴露出来的 V8 内部结构很有趣,但 valueOf()
自 1997 年 ECMAScript 1 以来就已经存在,因此并不新鲜。您还没有解决我的观点,即当两个操作数属于同一类型时会发生什么的问题。将operator ==
和operator ===
添加到您的示例中,您会看到它们都没有出现在您的actions
数组中。
这真的应该是答案,imo。 == 调用 === 然后尝试强制以查看它是否以其他方式相似。那么,当您尝试比较身份时,=== 对于不相等的对象显然更快。【参考方案4】:
由于性能,我认为===
的性能更好,因为===
比==
更严格,
例如在 Chrome 控制台中尝试以下操作。
> 1 == '1'
true
> 1 === '1'
false
==
必须检查的东西比===
还要多
【讨论】:
【参考方案5】:从一些脆弱的测试来看,==
似乎比===
稍微快一些。
我的意思是,我可以在数百万次测试的交互中看到几毫秒的差异。您不可能需要性能提升,而不是使用最适合手头任务的方法。
编辑:实际上,似乎取决于您要比较的 /what/ 和浏览器实现。换句话说,不用担心。
【讨论】:
===
在大多数情况下更快。有边缘情况(你找到了一个)。然而,从代码实践/风格指南===
每次都能胜出
“别担心”,“你不可能需要性能提升”。你不知道这个用户的意图,以及所有来这里问这个问题的用户。
@cdosborn 哇,你好 2011。这个 Q 早于 SO 上的 nodejs 标签。是的,你是对的。当时这是一个公平的假设,这是在浏览器中,并且削减毫秒/数百万次评估将是.. 对您的时间的错误利用。大约 5 年的时间里,情况发生了很大变化。【参考方案6】:
这取决于被比较的项目。由于“===”比“==”更严格,它应该比“==”更快地返回false。但是,如果这两个项目严格相等,“===”应该比“==”花费更多的时间,因为它必须检查更多的属性是否相等。
【讨论】:
你有比较的来源吗?其他答案提到差异可以忽略不计 性能方面的差异基本上可以忽略不计,但仍然存在 请进一步解释——它为什么存在?真的可以忽略不计吗?最好根据事实写出答案,以便其他人可以从中学习以上是关于双等号 (==) 和三等号 (===) 之间的 JavaScript 性能差异的主要内容,如果未能解决你的问题,请参考以下文章