【问题标题】:Which is faster: Math.abs(value) or value * -1 ?哪个更快: Math.abs(value) 或 value * -1 ?
【发布时间】:2009-01-14 04:22:38
【问题描述】:

很简单,但我只想知道哪个更快。

我认为简单地将一个数字乘以 -1 比调用预定义方法要快得多,前提是您确定该值为负数。

但如果是这样,那么abs() 函数是干什么用的?是否只是为了确保无论值的符号如何,返回的值始终为正数?

【问题讨论】:

标签: javascript performance


【解决方案1】:

我建议选择更清楚地表明您的意图的方法,而不是担心性能。在这种情况下,乘以 -1 的性能增益可能很小。

当你使用Math.abs() 时,很明显你想要一个正值。当您使用* -1 时不清楚,需要更多调查以确定输入值是否始终为负。

【讨论】:

  • +1。优化的第一条规则:“不要这样做”。优化的第二条规则(仅限专家!):“暂时不要这样做。” :-)
  • 最初我想不同意您的按书回答以避免过早的优化,因为 JS 由于被解释而缺少编译器优化.如果真的很重要,使用这些小技巧来提高性能是有意义的。然而,现代浏览器(jit-)编译 JS,使得这种优化越来越过时。
【解决方案2】:

2012 年 8 月更新

我对这些实现做了一些分析:

/* Test 1: */ b = Math.abs(a);
/* Test 2: */ b = abs(a); //local copy: abs = Math.abs;
/* Test 3: */ b = a < 0 ? a * -1 : a;
/* Test 4: */ b = a < 0 ? -a : a;

我在 Windows 7 上得到了以下结果。在每个浏览器的最快结果之后对值进行归一化,以便更容易比较哪种方法更快:

        1:Math 2:abs 3:*-1  4:-    1.0=   Version
Chrome    1.0   1.0   1.0   1.0    111ms  21.0.1180.75 m
Firefox   1.0   1.0   1.2   1.2    127ms  14.0.1
IE        1.4   1.0   1.1   1.0    185ms  9.0.8112
Opera     1.9   1.6   1.1   1.0    246ms  12.00
Safari    1.6   1.6   1.1   1.0    308ms  5.1.7

结论: 3 年前我做这个测试时,-a 是最快的,但现在 Math.abs(x) 在 Firefox 中更快!在 Chrome 中 abs(a)-a 得到了相同的时间,当我用 10 000 000 个数字测试它时,与最慢的方法只有 3 毫秒的差异。

我的建议:使用 Math.abs(a)。如果你在一个紧密的循环中并且通过分析发现它太慢了,你可以使用对 abs 函数的本地引用:

var abs=Math.abs; //A local reference to the global Math.abs function
for (i=0;i<1234567890;++i) if ( abs( v[i] ) > 10) ++x;

【讨论】:

    【解决方案3】:

    只是*-1 操作可能更快,但请记住,最终结果不同于 与 math.abs() 的结果。

    math.abs(-5)math.abs(5) 都返回 5。

    -5 * -1 也返回 5。

    5 * -1 返回 -5。

    因此,除非您绝对确定该数字一开始是负数,否则您必须进行一些测试,这会花费更多时间。还不如做 math.abs()。

    但实际上,如果 abs() 和 *-1 之间的性能差异在您的 JS 中很重要,那么您可能会遇到更严重的问题。

    【讨论】:

      【解决方案4】:

      我想这取决于实现,但Math.abs 可能很简单:

      function abs(x) {
          return x < 0 ? x * -1 : x;
      }
      

      因此,理论上,它只是在乘法之前添加一个快速测试。

      但是,是的,否定负号是唯一的目的。关键是简单的x * -1 对于正值也会适得其反。


      @olliej [cmets]

      没错。不过,简单的编辑。 ;)

      function abs(x) {
          return Number(x < 0 ? x * -1 : x);
      }
      

      【讨论】:

      • 技术上不正确,因为 abs 被定义为返回一个数字。如果我做了 abs(true) 或 abs(false),我应该得到 0 或 1,而你的函数将产生 true 或 false。函数 abs(x) { if (x
      • (随机事实:在当前的 WebKit nightlies 中实际上比使用 Math.abs 更快)
      • 您不希望调用 Number,这需要解析全局对象等。一元 + 完成了足够的工作。
      • 你可以使用内置的浏览器,而不是自己做abs: var abs = Math.abs;警报(abs(-1));
      【解决方案5】:

      一个风格问题:为什么使用a * -1 而不是-a? 除此之外,如果您事先不知道号码的符号,我同意您应该使用abs()。我不在乎速度,只在乎可读性。

      【讨论】:

        猜你喜欢
        • 2010-10-08
        • 1970-01-01
        • 2019-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-27
        • 2011-02-27
        相关资源
        最近更新 更多