我曾被许多程序员警告不要使用平方根函数,而是将数字提高到一半的幂。我的问题有两个:
这样做的感知/实际性能优势是什么?为什么更快?
如果它确实更快,为什么还要存在平方根函数?
我曾被许多程序员警告不要使用平方根函数,而是将数字提高到一半的幂。我的问题有两个:
这样做的感知/实际性能优势是什么?为什么更快?
如果它确实更快,为什么还要存在平方根函数?
我进行了一项简单测试:
Stopwatch sw = new Stopwatch();
sw.Start();
Double s = 0.0;
// compute 1e8 times either Sqrt(x) or its emulation as Pow(x, 0.5)
for (Double d = 0; d < 1e8; d += 1)
// s += Math.Sqrt(d); // <- uncomment it to test Sqrt
s += Math.Pow(d, 0.5); // <- uncomment it to test Pow
sw.Stop();
Console.Out.Write(sw.ElapsedMilliseconds);
在我的工作站(x64)上, (平均)结果为
Sqrt: 950 ms
Pow: 5500 ms
正如你所看到的,更具体地说,Sqrt(x)
比其仿真版本 Pow(x, 0.5)
快5.5倍。因此这只是又一个传说(至少在C#中),即Sqrt
速度非常慢,应该优先考虑使用Pow
代替。
sqrt
替换为Pow
,那么不这样做可能会获益。 - J...Sqrt
已经在硬件中实现,分别针对x87 FPU(32位)和SSE/SSE2(64位),使用这些函数进行计算比Pow
等软件实现要快得多。即使在具有f2xm1
、fyl2x
等实现的x87硬件上,单个调用f2xm1
(它只会让您开始实现Pow
)几乎与完整的fsqrt
一样昂贵,而fyl2x
的时间比fsqrt
长三倍以上。除非是非常特殊的边缘情况和巧妙的算法,否则Pow
没有办法更快。 - J...
exp(ln(x)/2)
。 - Blindysqrt
为pow
时会发现情况变得更糟。 - J...0x5f3759df
。 - Wai Ha Lee