Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What to do with Java BigDecimal performance?

I write currency trading applications for living, so I have to work with monetary values (it's a shame that Java still doesn't have decimal float type and has nothing to support arbitrary-precision monetary calculations). "Use BigDecimal!" — you might say. I do. But now I have some code where performance is an issue, and BigDecimal is more than 1000 times (!) slower than double primitives.

The calculations are very simple: what the system does is calculating a = (1/b) * c many many times (where a, b and c are fixed-point values). The problem, however, lies with this (1/b). I can't use fixed point arithmetic because there is no fixed point. And BigDecimal result = a.multiply(BigDecimal.ONE.divide(b).multiply(c) is not only ugly, but sluggishly slow.

What can I use to replace BigDecimal? I need at least 10x performance increase. I found otherwise excellent JScience library which has arbitrary-precision arithmetics, but it's even slower than BigDecimal.

Any suggestions?

like image 940
Alexander Temerev Avatar asked Mar 04 '09 17:03

Alexander Temerev


People also ask

What can I use instead of BigDecimal?

If you need to use division in your arithmetic, you need to use double instead of BigDecimal.

Why do we use BigDecimal in Java?

The BigDecimal class provides operations on double numbers for arithmetic, scale handling, rounding, comparison, format conversion and hashing. It can handle very large and very small floating point numbers with great precision but compensating with the time complexity a bit.

Why use BigDecimal instead of double in Java?

The BigDecimal(String) constructor should always be preferred over BigDecimal(Double) because using BigDecimal(double) is unpredictable due to the inability of the double to represent 0.1 as exact 0.1.

How do I stop rounding in BigDecimal?

56 if you use BigDecimal newValue = myBigDecimal. setScale(2, RoundingMode. DOWN); " This statement is true for HALF_DOWN not for DOWN mode.


2 Answers

May be you should start with replacing a = (1/b) * c with a = c/b ? It's not 10x, but still something.

If I were you, I'd create my own class Money, which would keep long dollars and long cents, and do math in it.

like image 158
Vladimir Dyuzhev Avatar answered Oct 18 '22 04:10

Vladimir Dyuzhev


Most double operations give you more than enough precision. You can represent $10 trillion with cent accuracy with double which may be more than enough for you.

In all the trading systems I have worked on (four different banks), they have used double with appropriate rounding. I don't see any reason to be using BigDecimal.

like image 22
Peter Lawrey Avatar answered Oct 18 '22 05:10

Peter Lawrey