2011-07-27 58 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