2

I have a Java application that uses the compareTo() method of the BigDecimal class in order to classify a (big) real number, read as a string, according to its type (basically, "too big", double or float). The application reads a very large number of such strings per second, so any performance optimization is essential.

Following is an abbreviated excerpt of the code:

static final BigDecimal MAX_LONG    = new BigDecimal(Long.MAX_VALUE);
static final BigDecimal MAX_FLOAT   = new BigDecimal(Float.MAX_VALUE);
static final BigDecimal MAX_DOUBLE  = new BigDecimal(Double.MAX_VALUE);

String value = readValue(); // Read the number as a string

BigDecimal number = new BigDecimal(value);

if (number.compareTo(MAX_DOUBLE) > 0)
{
    ...
}
else if (number.compareTo(MAX_FLOAT) > 0)
{
    ...
}
else if (number.compareTo(MAX_LONG) > 0)
{
    ...
}

So, 2 questions

  1. In a multithreaded environment, is it safe to make the above comparisons (given the static fields)?
  2. Is there any thread-safe and faster way of implementing the above classification?
PNS
  • 19,295
  • 32
  • 96
  • 143
  • 2
    *"any performance optimization is essential."* How did you come to the conclusion that this particular method had to be optimized? – NullUserException Oct 29 '12 at 22:50
  • I was referring to my code, not the compareTo() method. – PNS Oct 29 '12 at 22:52
  • 4
    The question stands; how did you come to the conclusion that this particular part of your code needs to be optimized? – NullUserException Oct 29 '12 at 22:56
  • 2
    You're wasting your time if you haven't profiled the code and determined this is an actual bottleneck. What's worse, if you haven't profiled your code, how do you know if the changes you made actually improve performance? With all the `if` statements, branch misprediction could very well *degrade* performance. – Confluence Oct 29 '12 at 23:06
  • I am primarily interested in verifying thread safety. Beyond that, any performance suggestion, like using valueOf() instead of the constructor, is welcome. – PNS Oct 29 '12 at 23:20
  • 2
    Performance improvements are only valid if you can verify they're actually improvements. Often times, optimization works in unexpected ways. – Confluence Oct 29 '12 at 23:23

2 Answers2

6

As BigDecimal is immutable it is also therefore thread-safe.

You should also use BigDecimal.valueOf() instead of new BigDecimal() throughout, to take advantage of any caching that may be possible.

user207421
  • 305,947
  • 44
  • 307
  • 483
1

I agree with those who questioned whether comparison really is a bottleneck. File or network IO time is more likely.

If comparisons really are a bottleneck and you make an IID or similar assumption about the data, then you'll need fewer comparisons if you keep a histogram counting the inputs that fall in each interval and reorder the tests on the fly so that the most frequent case is verified first.

For example, your current ladder of comparisons is best if there are many numbers greater than MAX_DOUBLE. Only one comparison per number is needed. But it's worst if most numbers are less or equal to than MAX_FLOAT, since then three comparisons per number will be needed.

Gene
  • 46,253
  • 4
  • 58
  • 96