JavaScript - === vs ==运营商的表现

问题描述 投票:20回答:6

几个星期前,我在Is < faster than <=?上读过关于比较运算符的这个主题C。据说<<=之间的性能没有差异,因为它们被解释为相同/相似的机器命令。

同时,在我们公司的“最佳实践”中,据说我们应该总是使用“===”来比较事物而不是“==”。所以,我开始怀疑这是否总是合适的,因为我习惯使用“==”和“typeof ... ==”并且不想改变我的写作方式: - ]

请注意,这是在JavaScript的上下文中。

所以,我有一点研究,在这里Which equals operator (== vs ===) should be used in JavaScript comparisons?据说:

这是因为等于运算符==确实类型强制...意味着解释器隐式尝试转换值然后进行比较。

另一方面,身份运算符===不进行类型强制,因此它在比较时不会转换值的值

我开始怀疑这是否意味着当我使用“===”运算符时,我将获得良好的性能,因为没有资源将用于转换操作数。在将所有代码转换为机器命令之后,这是否意味着当使用C<<=没有区别,这在JavaScript和其他语言中是一样的吗?

javascript performance equality comparison-operators equality-operator
6个回答
-3
投票

对于js,如果在字符串类型上使用,则===运算符将返回true,并且字符串是完全相同的字符。对于对象,它比较对象引用,而不是内容。

来自ECMA standard

11.9.6严格的等式比较算法比较x === y,其中x和y是值,产生真或假。这样的比较如下进行:

  1. 如果Type(x)与Type(y)不同,则返回false。
  2. 如果Type(x)是Undefined,则返回true。
  3. 如果Type(x)为Null,则返回true。
  4. 如果Type(x)是Number,那么a。如果x是NaN,则返回false。湾如果y是NaN,则返回false。 C。如果x与y的Number值相同,则返回true。 d。如果x是+0且y是-0,则返回true。即如果x是-0且y是+0,则返回true。 F。返回false。
  5. 如果Type(x)是String,则如果x和y完全相同的字符序列(相应位置的长度和字符相同),则返回true;否则,返回false。
  6. 如果Type(x)是布尔值,如果x和y都为true或两者都为false,则返回true;

10
投票

首先,表现根本不是一个问题。对于任何真实的脚本,与代码中的其他瓶颈相比,使用一个运算符而不是另一个运算符的任何性能增益都是无限小的(通常DOM操作将是头号目标)。

其次,在许多情况下,=====将执行完全相同的步骤。当两个操作数的类型相同时(例如,两个字符串或两个数字),ECMAScript规范对于两个操作符具有完全相同的步骤。因此,如果您在一个浏览器或其他环境中观察到两个运算符之间在相同类型的操作数之间的性能差异,则无法保证甚至可能在另一个浏览器中看到类似的差异。

在你的问题中提到的typeof的情况下,两个操作数保证是相同的类型(字符串),并且两个操作符将完全相同的事情,因此支持一个操作符而不是另一个操作符的唯一理由是风格。

JS社区作为一个整体已经相当强硬:共识似乎是“从不使用==!=,除非你需要类型强制”,这对我的口味来说太教条了。


10
投票

我觉得答案很容易,可以证实的证据是最好的。

这些操作非常小,很难对它们进行性能测试。

  • == 1648是的
  • === 1629是的
  • 控制测试1575真实

如果你减去控制测试,看起来他们的浏览器速度差异约为30%。如果你多次这样做,你可以得到不同的答案,但===通常是最快的,我认为这只是对差异的微不足道的证明。

我认为这几乎证明了其他人在说什么,性能差异是浪费时间思考,但它也表明===实际上更快。希望这个答案可以节省其他人的时间,那些只需要看证明的人。

2019年更新

2019-04-09 Firefox改进测试:

  • == 1383是的
  • === 1167是的
  • 控制测试429是真的

2019-04-09 Chrome改进测试:

  • == 249是的
  • === 248是的
  • 控制测试248是真的

2019-04-09 Edge改进测试:

  • == 22510是的
  • === 20315是的
  • 控制测试4968是真的

浏览器多年来变得越来越聪明,看来我的原始测试已经遇到了Chrome和Firefox中的酷炫优化,使其不再有用。我使测试更难以优化并增加运行次数以再次获得有意义的结果。看起来===仍然更快。担心可能还是浪费时间。

var testString = "42";
var testString2 = "43";
var testString3 = "42";
var testNumber = 42;
var testNumber2 = 43;
var testNumber3 = 42;

var testObject = {};
var testObject2 = {};
var testObject3 = testObject;


var start = Date.now();
var result = null;
for(var i = 0; i < 200000000; i++){
	result = 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3
}

console.log("==", Date.now() - start, result);

var start = Date.now();
var result = null;
for(var i = 0; i < 200000000; i++){
	result =
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3
}
console.log("===", Date.now() - start, result);
var start = Date.now();
var alwaysTrue = true;
var alwaysFalse = false;
for(var i = 0; i < 200000000; i++){
	result = 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue
}
console.log("control test", Date.now() - start, result);

3
投票

无论你获得什么样的表现都没关系,在这种情况下,===显然是更好的选择。任何其他诸如更好的表现都只是锦上添花。此外,两种方式的差异都很小。


3
投票

这是一种脚本语言。这些运算符的性能应该没那么重要,你应该担心它,因为还有许多其他东西消耗更多的功能,比如它在虚拟机中运行的事实,是弱类型的,与HTML一起使用浏览器中的DOM ...

此外,两个运营商都做了很多不同的事情,所以在任何情况下都不可能与其他运营商互换。

也就是说,我认为(但尚未测试)===更快。原因是,它只需要比较类型,如果匹配,则比较原始数据。如果==运算符不匹配,它们会尝试将一种类型转换为另一种类型。在大多数情况下,这将是一个更昂贵的操作。

这是幸运的,因为在大多数情况下,===是更好的选择。 :)

但无论如何,您可以轻松地测试它(确保您测试多个案例,包括相同类型和几种不同类型),但如果您不知道如何测试它,我将完全不用担心它。差异,如果有的话,不会杀了你。


2
投票

性能差异可以忽略不计,这意味着你不应该浪费宝贵的大脑周期来思考它。如果你真的想知道,你应该测试。

使用===,除非你有充分的理由不(你可能不这样做)。

© www.soinside.com 2019 - 2024. All rights reserved.