BigDecimalの演算速度を検証しました。

検証の結果、以下のことがわかりました。
・ div/reminder は遅い
・ doubleのコンストラクタを使うと遅い
・ longのコンストラクタでも毎回newすると計算時間が増える。(まぁあたりまえだけど)
・ 桁が増えると遅くなる

BigDecimalは桁数に応じて内部データの持ち方を変えるようです。
桁が大きくなればなるほど遅くなると思われます。
データがintで表せる数である場合とlongで表せる数値の場合ではガクッと計算速度が変わります。

検証方法:
Core i 5 2500K 3.2GHz のマシンで100万回単純計算

検証コード:

import java.math.BigDecimal;
import java.math.MathContext;

public class Main {

	public static void main(String[] args) {
		long start,end;
		int repeat = 10000 * 100;

		start = System.currentTimeMillis();
		testAdd1D(repeat, 100000);
		end = System.currentTimeMillis();
		System.out.println("add1 loop内new double constructor 桁少なめ ms:" + (end - start));

		start = System.currentTimeMillis();
		testAdd1D(repeat, Long.MAX_VALUE);
		end = System.currentTimeMillis();
		System.out.println("add1 loop内new double constructor 桁多め ms:" + (end - start));

		start = System.currentTimeMillis();
		testAdd1L(repeat, 100000);
		end = System.currentTimeMillis();
		System.out.println("add1 loop内new long constructor 桁少なめ ms:" + (end - start));

		start = System.currentTimeMillis();
		testAdd1L(repeat, Long.MAX_VALUE);
		end = System.currentTimeMillis();
		System.out.println("add1 loop内new long constructor 桁多め ms:" + (end - start));

		start = System.currentTimeMillis();
		testAdd2(repeat, 100000);
		end = System.currentTimeMillis();
		System.out.println("add2 loop外new 桁少なめ ms:" + (end - start));

		start = System.currentTimeMillis();
		testAdd2(repeat, Long.MAX_VALUE);
		end = System.currentTimeMillis();
		System.out.println("sum2 loop外new 桁多め ms:" + (end - start));

		start = System.currentTimeMillis();
		testSub(repeat);
		end = System.currentTimeMillis();
		System.out.println("sub ms:" + (end - start));

		start = System.currentTimeMillis();
		testMul(repeat);
		end = System.currentTimeMillis();
		System.out.println("mul ms:" + (end - start));

		start = System.currentTimeMillis();
		testDiv(repeat);
		end = System.currentTimeMillis();
		System.out.println("div ms:" + (end - start));

		start = System.currentTimeMillis();
		testMod(repeat);
		end = System.currentTimeMillis();
		System.out.println("mod ms:" + (end - start));
	}

	public static BigDecimal testAdd1D(int repeat, double value) {
		BigDecimal sum = BigDecimal.valueOf(23423234.2344);
		for ( int i = 0; i < repeat; i++ ) {
			sum = sum.add(new BigDecimal(value));
		}
		return sum;
	}
	public static BigDecimal testAdd1L(int repeat, long value) {
		BigDecimal sum = BigDecimal.valueOf(23423234.2344);
		for ( int i = 0; i < repeat; i++ ) {
			sum = sum.add(new BigDecimal(value));
		}
		return sum;
	}

	public static BigDecimal testAdd2(int repeat, double value) {
		BigDecimal v = BigDecimal.valueOf(value);
		BigDecimal sum = BigDecimal.valueOf(23423234.2344);
		for ( int i = 0; i < repeat; i++ ) {
			sum = sum.add(v);
		}
		return sum;
	}

	public static BigDecimal testSub(int repeat) {
		BigDecimal sum = BigDecimal.valueOf(234342749.2342342);
		for ( int i = 0; i < repeat; i++ ) {
			sum = sum.subtract(new BigDecimal(1234234.234));
		}
		return sum;
	}

	public static BigDecimal testMul(int repeat) {
		BigDecimal d2 = BigDecimal.valueOf(1123234242.3421);
		for ( int i = 0; i < repeat; i++ ) {
			d2.multiply(new BigDecimal(122343.4));
		}
		return null;
	}

	public static BigDecimal testDiv(int repeat) {
		MathContext mc = new MathContext(20);
		BigDecimal d2 = BigDecimal.valueOf(122343412.3421);
		for ( int i = 0; i < repeat; i++ ) {
			d2.divide(new BigDecimal(12234.34), mc);
		}
		return null;
	}

	public static BigDecimal testMod(int repeat) {
		MathContext mc = new MathContext(20);
		BigDecimal d2 = BigDecimal.valueOf(1223434.123421);

		for ( int i = 0; i < repeat; i++ ) {
			d2.remainder(new BigDecimal(123423.234234),mc);
		}
		return null;
	}
}

出力:
add1 loop内new double constructor 桁少なめ ms:327
add1 loop内new double constructor 桁多め ms:625
add1 loop内new long constructor 桁少なめ ms:30
add1 loop内new long constructor 桁多め ms:90
add2 loop外new 桁少なめ ms:18
sum2 loop外new 桁多め ms:78
sub ms:411
mul ms:444
div ms:971
mod ms:1275

Leave a Reply

(required)

(required)


9 × one =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>