2
new BigDecimal("10000");
new BigDecimal(10000);

I know the string constructor is used if the number is bigger than the compiler would accept, but are either of the constructors faster than the other?

Bond
  • 16,071
  • 6
  • 30
  • 53
MCMastery
  • 3,099
  • 2
  • 20
  • 43
  • Why don't you try it yourself? Call these constructors several thousand times and measure the needed time. And maybe read this: [How do I write a correct micro-benchmark in Java?](http://stackoverflow.com/a/513259) – Tom Jul 05 '15 at 16:03
  • See http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/math/BigDecimal.java – rossum Jul 05 '15 at 16:05
  • According to this SQ question the double constructor is deprecated: http://stackoverflow.com/questions/1056722/why-is-the-bigdecimaldouble-d-construction-still-around – bish Jul 05 '15 at 16:07
  • @bish No one uses that constructor here, so it isn't important :). – Tom Jul 05 '15 at 16:07
  • @rossum I already looked at that actually ;) but it didn't make that much sense. – MCMastery Jul 05 '15 at 16:08
  • logically, second constructor must be faster – Andrew Tobilko Jul 05 '15 at 16:08
  • @AndrewTobilko that's what I thought but I wanted to be sure – MCMastery Jul 05 '15 at 16:08
  • 1
    @MCMastery, open class `BigDecimal` and compare those two constructors, what is the problem? – Andrew Tobilko Jul 05 '15 at 16:11

5 Answers5

4

Passing a String to the constructor of BigDecimal requires a parsing of the String and a check char by char.

Passing an int is faster because it results only in a single assignment.

In any case the time difference is not signifiant.

Here the code of BigDecimal with an int parameter:

public BigDecimal(int val) {
    intCompact = val;
}

The code of BigDecimal constructor with a String calls BigDecimal(char[], int, int) that has around 140 rows of code.

Davide Lorenzo MARINO
  • 26,420
  • 4
  • 39
  • 56
  • 1
    Still wondering why this answer that was posted 15 mins back had no upvotes even though it is better than the accepted answer. +1 from me. – Chetan Kinger Jul 05 '15 at 16:24
4

I know the string constructor is used if the number is bigger than the compiler would accept

That's not the only reason for using the String constructor. Another reason for using the String constructor is to keep the value as-is when the BigDecimal is created.

If you don't really care about precision, you should stick to using double instead of BigDecimal.

but are either of the constructors faster than the other

This is something you have to find out yourself by benchmarking your code. That being said, you should prefer using the valueOf method instead of creating a new BigDecimal since valueOf will return cached values. (Currently, this ranges from 0 to 10 but this range can be higher for different JVM implementations and future implementations of the HotSpot VM as well so you are better of using valueOf)

Chetan Kinger
  • 15,069
  • 6
  • 45
  • 82
4

You can look at source code.

public BigDecimal(int val) {
    intCompact = val;
}

public BigDecimal(String val) {
    this(val.toCharArray(), 0, val.length());
}

public BigDecimal(char[] in, int offset, int len) {
       ...very long
}

Obviously, who is faster.

Zephyr Guo
  • 1,083
  • 1
  • 8
  • 14
1

The Constructor new BigDecimal(10000) should be faster because it does not have to convert a string into a number. The under-the-hood there has to be a cast or another call to a string function which would cause some additional overhead.

public class benchmark {

    public static void main(String [ ] args) {
        timeFunction();
    }

static void timeFunction() {
     long startTime = System.nanoTime();

     BigDecimal v1 = new BigDecimal("10000");
     System.out.println("new BigDecimal(\"10000\") : " + (System.nanoTime() - startTime) / 1000000 + " ms");

     startTime = System.nanoTime();

     BigDecimal v2 = new BigDecimal(10000);
     System.out.println("new BigDecimal(10000) : " + (System.nanoTime() - startTime) / 1000000 + " ms");
}

}

OUTPUT

new BigDecimal("10000") : 4 ms
new BigDecimal(10000) : 0 ms
Matt
  • 879
  • 9
  • 29
  • 4
    no-no, very bad way. I would advise [**jmh**](http://openjdk.java.net/projects/code-tools/jmh/) – Andrew Tobilko Jul 05 '15 at 16:15
  • Microbenchmark are strongly influenced by many factors. The best way is to repeat the code several time before timing it. But in microbenchmarks creation of new Objects is really influenced by garbage collector. So the best is to microbenchmark eventually the code inside the constructor... not the constructor itself – Davide Lorenzo MARINO Jul 05 '15 at 16:18
  • I agree with Andrew, this may not be the best way to track benchmarks if you want a true analysis of the time difference, however, it demonstrates that the Big Decimal using string will take longer. – Matt Jul 05 '15 at 16:18
0

Find the time difference yourself & analyse. Like :-

BigDecimal big = null;
long startTime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
    big = new BigDecimal("10000");
}
long endTime = System.currentTimeMillis();
System.out.println("time Taken In String : " + (endTime - startTime));

startTime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
    big = new BigDecimal(10000);
}
endTime = System.currentTimeMillis();
System.out.println("time Taken in Numeric : " + (endTime - startTime));

PS:- Keep in consideration the Garbage Collection. Consider the above code as a reference only.

AnkeyNigam
  • 2,810
  • 4
  • 15
  • 23