3

Consider an application that

  1. Reads several thousands of String values from a text file.
  2. Selects (via a regular expression match) those values that represent a number (from simple integers to very large values written in scientific notation with mantissa).
  3. For each String value representing a number, instantiates a BigDecimal object (at a total rate of thousands of Bigdecimal objects per second).
  4. Uses each instantiated BigDecimal object for further processing.

Given the above scenario, obviously the instantiation of each BigDecimal object has an impact on performance.

One way to instantiate those BigDecimal objects from a non-null String str, is:

BigDecimal number = new BigDecimal(str.toCharArray(), 0, str.length()));

which is exactly what the String constructor of BigDecimal expands to in the Oracle implementation of the JDK.

Is there a faster way of instantiating BigDecimal objects from such strings, or via an alternative approach?

PNS
  • 19,295
  • 32
  • 96
  • 143
  • The BigDecimal API shows you the constructors that are available. If you have a concern about this, then consider profiling them. – Hovercraft Full Of Eels Nov 03 '12 at 13:58
  • I have looked at the constructors, hence the expansion from string to the form presented in the question. What I am wondering is whether there is a simple alternative that I have not thought about yet. – PNS Nov 03 '12 at 14:01
  • 2
    What else is there besides what is listed in the API? I think that with BigDecimal, you're going to have to accept a performance hit as the price for the greatly improved precision, and that there is no way around this other than to not use BigDecimal and to thus forgo the precision. – Hovercraft Full Of Eels Nov 03 '12 at 14:06
  • Optimizing `BigDecimal` sound like premature optimization to me. If the *complete* process is really to slow I would also look whether the complete IO handling and, especially, the regexp stuff can be optimized. Regexps are more expensive than most people think at first. – A.H. Nov 03 '12 at 14:09
  • @Hovercraft: This is more or else what I am asking. For instance, BigDecimal has some valueOf() constructors, which are supposed to be higher performance but are not for String values. My guess is that not much more can be done. – PNS Nov 03 '12 at 14:11
  • @A.H. You are right. I was just wondering whether I am missing something obvious. – PNS Nov 03 '12 at 14:12

3 Answers3

4

I would use

BigDecimal number = new BigDecimal(str);

which is simpler and the difference is unlikely to matter.

If you need performance and you don't need more than 15 digits of accuracy you can use double instead.

You need to performance I would look at the performance of your whole application before micro-optimising. You mention using a regular expression and this can use more CPU than creating strings or BigDecimal. Can you profile your application?

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Agreed on the performance issue. It seems to me that, given the regular expression I need to match anyway, I should check the number string and, if it is not too large (i.e., up to long or double with less than 17 decimal digits) I could use a primitive type directly. As for the constructor, you are right, but the "expanded" version saves 1 method call. :-) – PNS Nov 03 '12 at 15:05
1

I would agree that difference is unlikely to matter, however I would use valueOf as future versions of java are likely going to cache a lot of the common numbers.

bluesman
  • 2,242
  • 2
  • 25
  • 35
  • Using valueOf() is indeed preferable, but it does not apply for String values. – PNS Nov 03 '12 at 15:06
  • @PNS nothing stops you from parsing to double – bluesman Nov 04 '12 at 06:10
  • There may be bigger numbers than double and also creating a double and then instantiating a BigDecimal seems too much of an effort. – PNS Nov 12 '12 at 21:14
  • Also, involving Doubles in BigDecimal calculations leaves you open to [all sorts of rounding issues](http://stackoverflow.com/questions/460755/new-bigdecimal13-3d-results-in-imprecise-13-3000000000000007105?rq=1). – DuncanKinnear Nov 26 '12 at 20:08
  • @DuncanKinnear I'm not sure if you read the accepted answer, especially the "moral of the story" part. – bluesman Nov 27 '12 at 17:42
0

If there are lots of numbers that are likely to be the same, then maybe a HashMap<String, BigDecimal> 'cache' of BigDecimal values might be faster.

DuncanKinnear
  • 4,563
  • 2
  • 34
  • 65