开发者

Performance of BigDecimal.valueOf( double d )

I have a piece of code that needs to repetitively calculate the following...

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

This is used for generating random-ish information for testing. It seemed to be running slower than I would expect and I found that the slow part was BigDecimal.valueOf( consumption ) and that is slow because of the Double.toString() call that is happening internally.

The overall requirement is to generate a consumption value that is randomly between a minimum and maximum. Then add that to the currentReading to get a new reading.

Is there any way I can improve the performance of this? Perhaps b开发者_如何学Goy avoiding the double -> BigDecimal conversion. I need to the result to be a BigDecimal but I don't mind how the random calculation is done prior to that.


Instead of calculating a double you want to round to two decimal places, you can create an int value which is shifted by two places i.e. where 1234 represents 12.34 and then set the scale when you create the BigDecimal. i.e. dividing it by 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);

}

prints

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜