math.abs 的 Java 性能问题
我正在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我希望一个好的 JIT 能够将 Math.abs 调用内联到单个指令。如果您的代码在 FPU 上运行(很可能),使用
float
不会为您带来任何速度,因为几乎所有 FPU 都是 64 位或更好。然而,该算法如此不寻常的原因是,当其操作数的大小约为 10^150 时,它可以防止溢出。如果您正在考虑使用
float
,您的操作数的大小不得大于 10^38 左右,这意味着最快的算法将是: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), usingfloat
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:你的方法对于消极的论点不起作用。 添加:
只需在函数开始时 一切都应该很好。 (我所说的“不起作用”是指它并不总是以最小化舍入误差和溢出风险的方式进行计算。)
Your approach will not work for negative arguments. Just add:
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.)