2011-07-27 25 views
2

的我有一段代码,需要重复计算下面...性能BigDecimal.valueOf(双d)

 double consumption = minConsumption + (Math.random() * ((maxConsumption - minConsumption) + 1)); 
     currentReading = currentReading.add(BigDecimal.valueOf(consumption)).setScale(2, RoundingMode.HALF_EVEN).stripTrailingZeros(); 

这是用于产生用于检测随机肥胖型信息。它似乎比我预期的要慢,我发现缓慢的部分是BigDecimal.valueOf(consumption),并且由于内部发生的Double.toString()调用而缓慢。

总体要求是生成一个随机在最小值和最大值之间的消耗值。然后将其添加到currentReading以获得新的读数。

有什么办法可以提高这个性能吗?也许通过避免double - > BigDecimal转换。我需要的结果是一个BigDecimal,但我不介意如何在这之前完成随机计算。

+0

你的意思BigDecimal.valueOf(双)? –

+1

是什么让你觉得这是一个性能问题?你有什么数据吗?如果不是,我怀疑你有过早的优化。 – duffymo

+0

我已经运行它,并暂停了很多。调试程序在Double.toString()代码中停止该调用的90%时间。 –

回答

7

您可以创建一个int值,并将其移位两位,即1234代表12.34,然后在创建BigDecimal时设置比例尺,而不是计算双精度值。即除以100个

double min = 100; 
double max = 10000000; 
{ 
    long start = 0; 
    int runs = 1000000; 
    for (int i = -10000; i < runs; i++) { 
     if (i == 0) 
      start = System.nanoTime(); 
     double consumption = min + (Math.random() * ((max - min) + 1)); 

     BigDecimal.valueOf(consumption).setScale(2, BigDecimal.ROUND_HALF_UP); 
    } 
    long time = System.nanoTime() - start; 
    System.out.printf("The average time with BigDecimal.valueOf(double) was %,d%n", time/runs); 
} 
{ 
    long start = 0; 
    int runs = 1000000; 
    int min2 = (int) (min * 100); 
    int range = (int) ((max - min) * 100); 
    Random rand = new Random(); 
    for (int i = -10000; i < runs; i++) { 
     if (i == 0) 
      start = System.nanoTime(); 
     int rand100 = rand.nextInt(range) + min2; 
     BigDecimal bd = BigDecimal.valueOf(rand100, 2); 
    } 
    long time = System.nanoTime() - start; 
    System.out.printf("The average time with BigDecimal.valueOf(long, int) was %,d%n", time/runs); 

} 

打印

The average time with BigDecimal.valueOf(double) was 557 
The average time with BigDecimal.valueOf(long, int) was 18 
+0

谢谢你做到了。现在速度更快,没有明显的瓶颈。 –

+0

卓越知识+1 – mKorbel