javascript中最快的斜边?

javascript中最快的斜边?,javascript,math,approximation,Javascript,Math,Approximation,我在javascript中看到了许多关于模拟和动画的问题,这些问题通常涉及计算斜边: hypot = Math.sqrt(x*x + y*y); 由于笛卡尔坐标是这些引擎中的首选武器,因此需要进行这些计算以找到点对之间的距离等。因此,计算斜边时的任何加速都可能对许多项目有很大帮助 为此,您能看到比上述简单实现更快的方法吗?我发现了一个近似值,在Chrome中稍微快一点,但在Firefox中却慢得多,基于 编辑2015-08-15:我已将已接受的答案转换为数学答案;我怀疑目前的实用方法是使用Ma

我在javascript中看到了许多关于模拟和动画的问题,这些问题通常涉及计算斜边:

hypot = Math.sqrt(x*x + y*y);
由于笛卡尔坐标是这些引擎中的首选武器,因此需要进行这些计算以找到点对之间的距离等。因此,计算斜边时的任何加速都可能对许多项目有很大帮助

为此,您能看到比上述简单实现更快的方法吗?我发现了一个近似值,在Chrome中稍微快一点,但在Firefox中却慢得多,基于


编辑2015-08-15:我已将已接受的答案转换为数学答案;我怀疑目前的实用方法是使用Math.Hypto或合成Hypto函数(如果不可用),并与平方(根据sch的回答)进行比较(如果这足够且Math.Hypto不可用)。

通常,您不需要计算平方根,并且
Hypto^2=x*x+y*y
就足够了。例如,如果要比较距离,而不需要实际值,则会出现这种情况

您可以查看
x
y
的相等性。如果a等于,则可以将斜边计算为
(x+y)/sqrt(2)
,其中
sqrt(2)
是一个常数

所以这个方法可以用于x=y的情况。在其他情况下,它的最大不精确度可达41%。这是一个很大的错误。但当您指定允许的误差限制时,可以使用此方法。例如,如果将允许误差定义为5%,则可以得出
b
必须介于
0.515*a
1.942*a
之间

因此,如果您不需要完美的计算不精确性,您可以使用一系列值来提高计算性能

通过类比,您可以看到
x
y
0
相等。在这种情况下,计算斜边的速度会更快


另外,我在《一》中读到了这一点。

许多人不知道的一个要点:

hypot=Math.sqrt(x*x+y*y)

这在理论上是可行的,但在实践中可能会失败。如果x这么大 如果x*x溢出,代码将产生无限的结果

下面是如何计算sqrt(xx+yy)而不冒溢出风险

max = maximum(|x|, |y|)
min = minimum(|x|, |y|)
r = min / max
return max*sqrt(1 + r*r)

参考和完整文本:John D.Cook-

在ECMAScript ES6中,您可以使用

//ES5支持
Math.hypot=Math.hypot | |函数(x,y){返回Math.sqrt(x*x+y*y)}
变量x=3,y=4;

document.write(Math.hypot(x,y))
Math.hypot()的性能取决于javascript运行环境

我只是在Node.js、Chrome和Firefox中运行以下代码:

let z = performance.now();
for (let i = 0; i < 1000000000; i++) {
    Math.hypot(i, i);
}
console.log(performance.now() - z);

z = performance.now();
for (let i = 0; i < 1000000000; i++) {
    Math.sqrt(i * i + i * i);
}
console.log(performance.now() - z);
铬88.0.4324.150:

26474.060000036843
422.13000007905066
Firefox 85.0.2:

423
419
这意味着V8的Math.hypot()实现非常糟糕。事实上,如果它还依赖于CPU体系结构/模型,我也不会感到惊讶


注意,在我的示例中,我将整数输入到
Math.sqrt()
Math.hypot()
。另一项测试显示,对于浮点数,Node.js运行测试代码的速度比整数慢20%。在Chrome中,
Math.sqrt()
性能完全相同,
Math.hypot()
运行速度慢了3%。Firefox:没有区别。

你可以随时使用它,你想加速使用毕达哥拉斯公式的每一个脚本是很高尚的。然而,我认为不存在使公式更快的通用解决方案(否则我们就不会使用2500年前的版本)。与其试图加快公式的速度,不如尝试重构代码,以便减少使用公式的次数,而且只有在证明公式是代码性能的瓶颈之后。@Kevin:在C或其他一些开销较低的语言中,确实有一些近似方法可以加快速度。近似值是否有用取决于模型所需的准确性,但对于游戏物理而言,如果它能使游戏更流畅,则通常是值得的。@PhilH,我同意你的两个观点,即存在更快的近似值,如果它能改善用户体验,则使用它们是值得的。但您需要逐案调查公式的每次使用,以判断特定近似值是否合适和值得。我只是说不存在万能的灵丹妙药,只有在你知道你需要它之后才应该进行优化。@yes。&我担心会出现非建设性的标记~但这是一个非常漂亮的标记;)(加一)最好提及诸如溢出计算等实现问题。加一个细节,确保
x
y
中至少有一个非零,否则结果将是
infinity
@PhilH Edit,我用Math.sqrt和Math.hypot测试了该操作,您可以看到它。在本测试中,使用了Math.hypot的原始函数
hypot
在Chrome 62上始终显示较慢。我试图将它放在一个严格的函数中以最小化外部干扰(),但sqrt仍然是更快的操作。也许他们在某个时候增加了一些防止溢出/下溢的保护?在我的chrome版本68.0.3440.106和16 GB RAM上,2.7 GHz Intel Core i7,Math,sqrt大约快25%。例77对302毫秒
423
419