我有以下简单的程序,它可以多次乘以两个不同的浮点数。如您所见,其中一个数字非常小。当我计算执行两次乘法的时间时,我很惊讶这个小数字比另一个需要更长的时间。看起来使用小双打的速度较慢......有谁知道发生了什么?
public static void main(String[] args) throws Exception
{
long iterations = 10000000;
double result;
double number = 0.1D;
double numberA = Double.MIN_VALUE;
double numberB = 0.0008D;
long startTime, endTime,elapsedTime;
//Multiply numberA
startTime = System.currentTimeMillis();
for(int i=0; i < iterations; i++)
result = number * numberA;
endTime = System.currentTimeMillis();
elapsedTime = endTime - startTime;
System.out.println("Number A) Time elapsed: " + elapsedTime + " ms");
//Multiply numberB
startTime = System.currentTimeMillis();
for(int i=0; i < iterations; i++)
result = number * numberB;
endTime = System.currentTimeMillis();
elapsedTime = endTime - startTime;
System.out.println("Number B) Time elapsed: " + elapsedTime + " ms");
}
结果:
Number A) Time elapsed: 3546 ms Number B) Time elapsed: 110 ms
Platform Windows,Java 1.6.0_07
谢谢, 迭
答案 0 :(得分:3)
在IEEE 758浮点值的最小表示附近运行时,您可能会得到“denormal”的结果。这些有时(尽管不总是)处理得更慢。我怀疑JVM是以某种方式专门处理它们而不是依靠纯硬件支持,导致性能下降。
答案 1 :(得分:2)
我的猜测是编译器替换了
number * numberB;
具有确切的值,因为number
和numberB
都是常量值,编译器知道这些值在该点没有改变。但是,numberA
不是常量值(其值是特定于平台的),因此您必须每次都进行实际计算。尝试将Double.MIN_VALUE
替换为其实际值,并查看它们是否表现相似。
答案 2 :(得分:0)
可能是您输入“非正常”数字的范围(请参阅IEEE754格式)。处理这些数字可能需要更多时间在浮点单元中。
答案 3 :(得分:0)
在Windows JVM中似乎是一个错误