我正在使用Jama matrix执行SVD操作。我有几个关于表现的问题。
我并不担心这么多准确性,我认为double比Float更准确,对吗?如果我使用浮动而不是双倍,它会提高性能并降低准确度吗?
在Jama矩阵中,它使用了一个它调用很多的函数,它使用了double和Math.abs函数,这需要大量的Heap和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;
}
我不知道,这是不是一个好方法。 感谢
答案 0 :(得分:6)
我希望有一个好的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);
}
答案 1 :(得分:1)
您的方法不适用于否定论点。只需添加:
if (a < 0) a = -a;
if (b < 0) b = -b;
在你的功能开始时,一切都应该很好。 (“不工作”我的意思是它不会总是以最小化舍入误差和溢出风险的方式进行计算。)