math.abs 的 Java 性能问题

发布于 2024-10-19 13:14:43 字数 1063 浏览 1 评论 0原文

我正在使用 Jama 矩阵 来执行 SVD 运算。我有几个关于性能的问题。

我并不担心那么多的准确性,而且我认为 double 比 Float 更准确,对吗?如果我使用 float 而不是 double,它会在多大程度上提高性能并降低精度?

在 Jama 矩阵中,它使用了一个调用很多的函数,它使用了 double 和 Math.abs 函数,这需要大量的堆和 CPU。如果我将其更改为 double 并删除 Math.abs,它会对性能和结果的准确性产生多大影响?

这是 Jama 数学函数:

   public static double hypot(double a, double b) {
      double r;
      if (Math.abs(a) > Math.abs(b)) {
         r = b/a;
         r = Math.abs(a)*Math.sqrt(1+r*r);
      } else if (b != 0) {
         r = a/b;
         r = Math.abs(b)*Math.sqrt(1+r*r);
      } else {
         r = 0.0;
      }
      return r;
   }

这是我想用这个函数做什么

   public static float hypot(float a, float b) {
      float r;
      if (a > b) {
         r = b/a;
         r = (float) (a*Math.sqrt(1+r*r));
      } else if (b != 0) {
         r = a/b;
         r = (float) (b*Math.sqrt(1+r*r));
      } else {
         r = 0;
      }
      return r;
   }

,我不知道这是否是一个好方法。 谢谢

I am using Jama matrix to perform SVD operations. I have couple of questions regarding performance.

I am not worried about so much accuracy, and I think double is more accurate than Float, am I right? If I use float other than double, how much will it improve the performance and reduce accuracy?

In Jama matrix it uses one function that it calls a lot, it used double and Math.abs function, that requires a lot of Heap and CPU. If I change it to double and remove Math.abs, how much will it impact the performance and results in terms of accuracy?

Here is the Jama math function:

   public static double hypot(double a, double b) {
      double r;
      if (Math.abs(a) > Math.abs(b)) {
         r = b/a;
         r = Math.abs(a)*Math.sqrt(1+r*r);
      } else if (b != 0) {
         r = a/b;
         r = Math.abs(b)*Math.sqrt(1+r*r);
      } else {
         r = 0.0;
      }
      return r;
   }

Here is the what I am thinking to do with this function

   public static float hypot(float a, float b) {
      float r;
      if (a > b) {
         r = b/a;
         r = (float) (a*Math.sqrt(1+r*r));
      } else if (b != 0) {
         r = a/b;
         r = (float) (b*Math.sqrt(1+r*r));
      } else {
         r = 0;
      }
      return r;
   }

I do not know, if it is a good way to do it or not.
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

恏ㄋ傷疤忘ㄋ疼 2024-10-26 13:14:43

我希望一个好的 JIT 能够将 Math.abs 调用内联到单个指令。如果您的代码在 FPU 上运行(很可能),使用 float 不会为您带来任何速度,因为几乎所有 FPU 都是 64 位或更好。

然而,该算法如此不寻常的原因是,当其操作数的大小约为 10^150 时,它可以防止溢出。如果您正在考虑使用 float,您的操作数的大小不得大于 10^38 左右,这意味着最快的算法将是:

public static double hypot(double a, double b) {
    return Math.sqrt(a * a + b * b);
}

I would expect a good JIT to inline a Math.abs call to just a single instruction. If your code is running on an FPU (quite likely), using float will not gain you any speed because nearly all FPUs are 64-bit or better.

However, the reason that the algorithm is so unusual is that it prevents overflow when the magnitude of its operands are on the order of 10^150. If you are considering using float, your operands must not be of magnitude larger than around 10^38, meaning that the fastest algorithm will just be:

public static double hypot(double a, double b) {
    return Math.sqrt(a * a + b * b);
}
十秒萌定你 2024-10-26 13:14:43

你的方法对于消极的论点不起作用。 添加:

if (a < 0) a = -a;
if (b < 0) b = -b;

只需在函数开始时 一切都应该很好。 (我所说的“不起作用”是指它并不总是以最小化舍入误差和溢出风险的方式进行计算。)

Your approach will not work for negative arguments. Just add:

if (a < 0) a = -a;
if (b < 0) b = -b;

at the start of your function and all should be well. (By "not work" I mean that it will not always do the calculation in a way that minimizes rounding errors and risk of overflow.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文