【问题标题】:Is Object.is(x,y) faster than other comparisons?Object.is(x,y) 比其他比较快吗?
【发布时间】:2019-07-11 06:23:58
【问题描述】:

所以在 JavaScript 中我们有三个相等比较运算符。我一直在阅读 ECMAScript 规范并研究它们是如何工作的。有什么东西打动了我。 Object.is() 内置函数的比较步骤更少,并且比其他运算符更早终止。那么这是否使Object.is() 的运行速度比其他运算符更快?

这里是sn-ps的规范:

Object.is()

  1. 如果 Type(x) 与 Type(y) 不同,则返回 false。
  2. 如果 Type(x) 是数字,那么

    一个。如果 x 是 NaN 而 y 是 NaN,则返回 true。

    b.如果 x 为 +0 且 y 为 -0,则返回 false。

    c。如果 x 是 -0 并且 y 是 +0,返回假。

    d。如果 x 与 y 的数值相同,则返回 true。

    e。返回 false。

  3. 返回 SameValueNonNumber(x, y)。

松散等于==

比较 x == y,其中 x 和 y 是值,产生 true 或 错误的。这样的比较是这样进行的:

  1. 如果 Type(x) 与 Type(y) 相同,那么

    一个。返回执行严格等式比较的结果 x === y。

  2. 如果 x 为 null 而 y 未定义,则返回 true。
  3. 如果 x 未定义且 y 为 null,则返回 true。
  4. 如果 Type(x) 是 Number 并且 Type(y) 是 String,则返回比较结果 x == ! ToNumber(y)。
  5. 如果Type(x) 是String,Type(y) 是Number,返回比较结果! ToNumber(x) == y。
  6. 如果 Type(x) 是布尔值,则返回比较结果! ToNumber(x) == y。
  7. 如果 Type(y) 是 Boolean,则返回比较结果 x == ! ToNumber(y)。
  8. 如果 Type(x) 是字符串、数字或符号且 Type(y) 是 Object,则返回比较结果 x == ToPrimitive(y)。
  9. 如果 Type(x) 是 Object 并且 Type(y) 是 String、Number 或 Symbol,则返回 ToPrimitive(x) == y 的比较结果。
  10. 返回 false。

严格等于 ===

比较 x === y,其中 x 和 y 是值,产生 true 或 错误的。这样的比较是这样进行的:

  1. 如果 Type(x) 与 Type(y) 不同,则返回 false。

  2. 如果 Type(x) 是数字,那么

    一个。如果 x 是 NaN,则返回 false。

    b.如果 y 是 NaN,则返回 false。

    c。如果 x 与 y 的数值相同,则返回 true。

    d。如果 x 为 +0 且 y 为 -0,则返回 true。

    e。如果 x 为 -0 且 y 为 +0,则返回 true。

    f。返回 false。

  3. 返回 SameValueNonNumber(x, y)。

如果从事 JavaScript 编译器工作的人可以回答这个问题,那就太好了!

【问题讨论】:

  • 最好的检查方法是通过测试。请参阅来自 jsPerf 的 this。根据这些测试,Object.is 在所有情况下确实更快。
  • @YongQuan 这不能将Object.is=== 进行比较。它将Object.is 与一个函数调用进行比较,其中包含一个条件,可能还有几个相等性检查和几个除法
  • @Paulpro 只是在网上找到另一个 jsPerf 测试。我上次搜索时有很多。您甚至可以编写自己的测试。
  • 所有对您的实施真正重要的性能问题都应该通过实际测试来解决。定义一些与您的特定代码相关的测试用例,并设计一个比较它们的 jsperf。看看哪种方式更快。尝试几个 JS 引擎,因为性能可能会有所不同。大多数情况下,实际代码中的差异可能毫无意义,但如果您真的很好奇,那么请设计一个代表您真正关心和衡量的测试用例的测试。猜想===猜测。测量 === 事实。
  • 请注意,=== 的第 2 步是标准的 IEEE 比较,因此可能有它的单指令版本。另一方面,Object.is 的第 2a 步是比较两个集合(因为NaN 有多个表示但它们都被视为等效),因此直接按位比较可能不够。

标签: javascript ecmascript-6


【解决方案1】:

规范中的步骤更少并不一定意味着实施中的步骤更少。各种优化都适用于此。所以最后,我们所能做的就是实际race the horses!(在您的真实世界用例中,一些合成的while(true) Object.is(1, 1); 不会产生任何有用的结果)。如果它真的(明显)更快,它是否会使您的代码更好,例如是

      Object.is(user.age, 3)

比清晰

      user.age === 3

?

【讨论】:

  • 在这种情况下,我很确定它的实施步骤更少。 ===Object.is() 没有强制转换。我知道=== 更干净,但这不是问题的重点:/ Tbh === 在这里显然是赢家,因为它和Object.is() 之间的唯一区别是:它不检查带符号的零,它不是函数调用。所以=== 更干净,甚至可能更快!但我希望有人给我一个确定的答案。
  • @BoškoBezik 如果您不比较不同类型的值,那么在性能敏感代码中,所有主要引擎都会优化类型检查和强制转换。这就是为什么== 通常和=== 一样快(在不使用强制转换的好代码中)。
  • @JonasWilms 如果您想查看已实现的代码,请成为我的客人。我不会为了看看哪个比较更快而遇到麻烦。所以我会“猜测”Object.is() 最快。 @Bergi 我知道现代编译器在优化代码方面非常出色。它很可能确实会被优化掉,因为在许多情况下,Google 的 V8 等引擎确实有多次优化。但尽管如此,我不会依赖于优化掉所有的小东西。
猜你喜欢
  • 1970-01-01
  • 2014-04-23
  • 2013-05-06
  • 1970-01-01
  • 2012-09-10
  • 1970-01-01
  • 1970-01-01
  • 2014-07-13
  • 2012-01-24
相关资源
最近更新 更多