2

次のコードを繰り返し計算する必要のあるコードがあります...

        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にする必要がありますが、その前にランダム計算がどのように行われるかは気になりません。

4

1 に答える 1

7

小数点以下2桁に丸めたい倍精度浮動小数点数を計算する代わりに、2桁シフトされた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
于 2011-07-27T10:17:49.547 に答える