BigDecimal

10進数で精度や桁落ち、丸め誤差などを極力行わないようにする場合、decimal型を使用します。使用するデータ容量は大きくなりますが、それでも比較的気軽に利用することができました。

一方、Android(Java)ではというと…BigDecimal型を使用します。ただ、Googleで検索したところ、おおむねBigDecimalは重いとか遅いなど注意を喚起するサイトをいくつか目にしました。ということで、doubleとどの程度差があるのか確認してみました。サンプルとして作成したソースは単純なループで加算を行うだけのものです。(使用した機種はHTC DsireとNexus Sです。)

[sourcecode language="java"]

public class BigDecimalSample extends Activity {

private static final String TAG = "BigDecimalSample";
private static final int counterMax = 10000;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    long doubleSt = System.currentTimeMillis();

    double d = 0d;

    // double の処理時間を確認する
    for(int i = 0;i < counterMax;i++) {
        d += i / 10;
    }

    Log.d(TAG, "Double = " + String.valueOf(d));

    long doubleEd = System.currentTimeMillis();

    TextView tvDouble = (TextView)findViewById(R.id.tv_double);
    tvDouble.setText("処理時間 : " + ((doubleEd - doubleSt)/1000.0) + "秒");

    long bigDecimalSt = System.currentTimeMillis();

    BigDecimal bd = new BigDecimal(0);

    // BigDecimalの処理時間を確認する
    for(int i = 0;i < counterMax;i++) {
        bd = bd.add(BigDecimal.valueOf(i/10));
    }

    Log.d(TAG, "BigDecimal = " + bd.toString());

    long bigDecimalEd = System.currentTimeMillis();

    TextView tvBigDecimal = (TextView)findViewById(R.id.tv_big_decimal);
    tvBigDecimal.setText("処理時間 : " + ((bigDecimalEd - bigDecimalSt)/1000.0) + "秒");
}

}

[/sourcecode]

結論としては、10,000回の加算を行った結果は次の通りでした。

HTC Desire double:0.005秒 / BigDecimal:0.122秒

Nexus S double:0.007秒 / BigDecimal:0.199秒

HTC DesireとNexus Sの両方で100倍以上の差があることが確認できました。ホントにBigDecimalは遅いのですね。とはいうものの、この程度であれば金額計算など必要な部分に適用するには十分ではないでしょうか。

確かに、スマートフォンは機器の制約が大きいと思いますが、ある程度実際にパフォーマンスを計測しながらホントのところを確認していく必要がありますね。