提高双重性能 - java

时间:2016-05-30 07:17:27

标签: java double

这是一个简单的java代码片段

float start = System.nanoTime();
for(int i=0;i<1000000000;i = i+1){}
float end = System.nanoTime();
System.out.println("Time taken : " + (end-start)/1000000000);

这将输出0.004194304秒,其中as:

for(double i=0;i<1000000000;i = i+1){}

此代码我只是将i的类型从int更改为double需要3.8970327秒。我的问题是如何在java中改进这种双重的非常糟糕的性能

2 个答案:

答案 0 :(得分:1)

首先,我认为你的int基准正在给出一个似是而非的答案。这个数字完全没有常识测试!

从1增加到1,000,000,000应该执行10亿增量,10亿个商店,10亿个测试,10亿个分支。所有这些都是据说在~0.004秒内发生。这意味着在0.004秒内有40亿条指令,或1秒钟内的1万亿条指令......或者是1.0E12的某个倍数的时钟速率。但是最快的英特尔处理器的时钟频率低于10 GHz ......或1.0E10。

事实上,我认为发生的事情是JIT编译器已经发现你的循环没有做任何有用的工作,并且已经优化了它

出于某种原因,JIT编译器还没有发现具有double的版本也没有做有用的工作。

但无论如何,使用单个处理器在3秒内进行10亿次浮点运算是非常好的表现......

  

我的问题是如何在java中改进这个非常糟糕的双重性能

  1. 性能不是很差。

  2. 这是(近似)真实的表现......你所看到的int表现是虚假的。

  3. 你无法改进它。

  4. 实际上,你很幸运double循环终止了。考虑这个版本:

     for (double i = 0; i < Integer.MAX_VALUE; i = i + 1){}
    
     for (float i = 0; i < Integer.MAX_VALUE; i = i + 1){}
    

    float版本应该更快。正确?

    错!

    问题是float只有24位(7.22位十进制数字)的精度。因此,介于1.0E7和1.0E8之间,由于四舍五入,您将得到i + 1评估为i的点。这会导致无限循环。

    当你考虑它时,正是这种事情可能导致JIT编译器不优化掉浮点循环。

答案 1 :(得分:-1)

这是正常的,因为int占用4个字节的内存,而double占用8个字节(它有小数)。 也许你可以证明BigDecimal。