Pow()与exp()表现

时间:2013-07-26 21:51:11

标签: javascript performance

我想知道exp()是否比更一般的pow()更快。我在JsPerf http://jsperf.com/pow-vs-exp上运行快速基准测试,它为我显示了有趣的结果。

Math.exp(logBase * exponent);  // fastest
Math.exp(Math.log(base) * exponent);  // middle
Math.pow(base, exponent);  // slowest

我知道结果会因架构和语言而异,但我也对理论观点感兴趣。将pow(a, b)实现为exp(log(a) * b)还是有一些更聪明的方式来“直接”计算能力(在C ++,C#或JavaScript中)。在某些体系结构上是否有针对exp,log或pow的CPU指令?

据我所知,exp()log()都是使用一些泰勒级数计算的,计算成本非常高。这让我相信,对于恒定的功率基础,这段代码

double logBase = log(123.456);
for (int i = 0; i < 1024; ++i) {
    exp(logBase * 654.321);
}

比这更好

for (int i = 0; i < 1024; ++i) {
    pow(123.456, 654.321);
}

这是正确的假设吗?

3 个答案:

答案 0 :(得分:10)

是的,exp一般会比pow快。

explog函数将针对目标平台进行优化;可以使用许多技术,例如Pade近似,线性或二进制缩减,然后近似等等。

pow函数通常会以exp(log(a) * b)的形式实现,因此它明显比单独exp慢。 pow有许多特殊情况,例如负指数,积分指数,等于1/2或1/3的指数等。这些将在一般情况下进一步减慢pow因为这些测试很贵。

请参阅this SO question on pow

答案 1 :(得分:1)

作为部分答案,有些架构上有exp,log或pow的说明。但是,这并不一定意味着很多。

例如,在x86上有

  • f2xm1计算2 x - 1
  • fscale计算y * ​​2 (int)x
  • fyl2x计算y * ​​log 2 x
  • fyl2xp1计算y * ​​log 2 (x + 1)(对输入范围有限制)

但是,它们使用不多。它从建筑到建筑各不相同,但它们永远不会快。作为一个更极端的例子,fyl2x在Sandy Bridge上有一个724的延迟(非常近期!),在同一个处理器上你可以做大约700个独立浮点加法,或者大约240个依赖浮点加法,或大约2000个独立的简单整数运算。

这和它一样糟糕,但它们通常很慢。足够慢,手动实施可以击败他们或至少不会明显失败。

此外,FPU代码正在慢慢消失,转而支持SSE代码。这些指令没有SSE等价物。

答案 2 :(得分:1)

无论架构详细信息如何,Math.pow都必须在错误检查方面做得更多(例如,如果基数为负,会发生什么?)。比Math.exp(因此我希望pow更慢)。

规范的相关部分:

http://ecma-international.org/ecma-262/5.1/#sec-15.8.2.8

  

15.8.2.8 exp(x)

     

返回指数的依赖于实现的近似值   x的函数(e增加到x的幂,其中e是x的基数)   自然对数)。

     

如果x是NaN,则结果为NaN。如果x为+0,则结果为1.如果x为   -0,结果为1.如果x为+∞,则结果为+∞。如果x是-∞,那么   结果是+0。

http://ecma-international.org/ecma-262/5.1/#sec-15.8.2.13

  

15.8.2.13 pow(x,y)

     

返回与结果相关的依赖于实现的近似值   将x提高到y。

     

如果y是NaN,则结果为NaN。如果y为+0,则结果为1,即使x为x   是NaN。如果y为-0,则结果为1,即使x为NaN。如果x是NaN和   y非零,结果是NaN。如果abs(x)> 1且y是+∞,则结果如此   是+∞。如果abs(x)> 1且y为-∞,则结果为+0。如果abs(x)== 1和y   是+∞,结果是NaN。如果abs(x)== 1且y为-∞,则结果为NaN。   如果abs(x)<1且y为+∞,则结果为+0。如果abs(x)<1且y是-∞,   结果是+∞。如果x是+∞且y> 0,则结​​果是+∞。如果x是+∞和   y <0,结果为+0。如果x是-∞且y> 0且y是奇数,则   结果是-∞。如果x是-∞且y> 0且y不是奇数,则   结果是+∞。如果x是-∞并且y <0并且y是奇数,则结果   是-0。如果x是-∞且y <0且y不是奇数,则结果为   + 0。如果x是+0且y> 0,则结​​果为+0。如果x是+0且y <0,则结果是+∞。如果x是-0且y> 0且y是奇数,则结果   是-0。如果x是-0且y> 0且y不是奇数,则结果为   + 0。如果x是-0并且y <0并且y是奇数,则结果是-∞。如果x是-0并且y <0并且y不是奇数,则结果是+∞。如果x <0   并且x是有限的,y是有限的,y不是整数,结果是   为NaN。