【问题标题】:Actual performance benefits of distance squared vs distance距离平方与距离的实际性能优势
【发布时间】:2016-05-30 19:54:40
【问题描述】:

在 Java 中计算两个 3D 点之间的距离时,我可以计算距离或它们之间的距离平方,避免调用 Math.sqrt。

本来,我读到 sqrt 只是乘法速度的四分之一,这使得使用距离平方的不便不值得。

在Java中,乘法和计算平方根之间的绝对性能差异是什么?

【问题讨论】:

  • “绝对”回答这个问题的唯一方法是对代码中的差异进行基准测试。 Obligatory link
  • 我的测试表明dx * dx + dy * dy 的运行速度大约是Math.sqrt(dx * dx + dy * dy) 的两倍。你提到了“四分之一的速度”,意思是4倍的差异。如果快 2 或 4 倍对您来说无关紧要,那也没关系,不是吗?在事情的整体方案中,只有你经常这样做才重要。 提防过早的优化。 如果您衡量一个问题,请修复它,不要根据(错误?)对性能的假设来混淆您的代码。
  • 计算距离是取平方距离的平方根。没有权衡,平方根是纯粹的开销。无论花费多长时间,计算正常距离所花费的时间都是比较平方距离的额外时间。
  • 您应该首先考虑什么是正确的解决方案,然后根据测量而不是猜测例如哪个代码花费最多时间来优化它。使用探查器。否则,您可能会花费大量时间优化代码,而这不会对您的应用程序整体性能产生任何影响。

标签: java performance distance sqrt math.sqrt


【解决方案1】:

我最初想将此添加为评论,但它开始变得太高,所以这里是:

自己试试吧。创建一个包含 10.000 次迭代的循环,您只需在其中计算 a*a + b*b,并在另一个单独的循环中计算 Math.sqrt(a*a + b*a)。计时,你会知道的。计算square root 本身就是一个迭代过程,其中数字(计算机位)平方根会收敛到更接近给定数字的实平方根,直到它足够接近(只要每次迭代之间的差异小于一些真正的小值)。除了Math 库使用的算法之外,还有多种算法,它们的速度取决于输入和算法的设计方式。在我看来,坚持Math.sqrt(...),不会出错,并且已经过很多人的测试。

虽然对于一个平方根来说这可以非常快地完成,但有一个明确的可观察到的时间差。

附带说明:我想不出多次计算平方根的理由,通常是在最后。如果您想知道点之间的距离,只需使用该距离的平方值作为默认值,并根据该默认值进行比较/求和/减法或任何您想要的。

PS:如果您想要更“实用”的答案,请提供更多代码

【讨论】: