0
    // Hideously slow program! Can you spot the object creation?
    Long sum = 0L;
    for (long i = 0; i < Integer.MAX_VALUE; i++) {
        sum += i;
    }
    end = System.currentTimeMillis();
    System.out.println("Long sum took: " + (end - start) + " milliseconds");
    
    long sum2 = 0L;
    for (long i = 0; i < Integer.MAX_VALUE; i++) {
        sum2 += i;
    }
    end = System.currentTimeMillis();
    System.out.println("long sum took: " + (end - start) + " milliseconds");

Hi, I am reading Effective Java and in Item 6:Avoid creating unnecessary objects, there is an example suggesting primitives to boxed primitives to avoid unnecessary object creation.

The author says, "Changing the declaration of sum from Long to long reduces the runtime from 43 seconds to 6.8 seconds on my machine." and continues, "The lesson is clear: prefer primitives to boxed primitives, and watch out for unintentional autoboxing".

But when I run it on my machine, the primitive version is slower than the boxed one.

The output of the program above:

Long sum took: 5905 milliseconds

long sum took: 7013 milliseconds

The results are not as expected as the author says, "The variable sum is declared as a Long instead of a long, which means that the program constructs about 2^31 unnecessary Long instances (roughly one for each time the long i is added to the Long sum)".

Why is using primitive slower than using object?

Community
  • 1
  • 1
Timuçin
  • 4,653
  • 3
  • 25
  • 34
  • 2
    It *can't* be slower - you are probably not measuring what you think you are measuring. Useful read: http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – assylias Aug 11 '14 at 07:18
  • 5
    The code above is missing a few declarations. Is it possible that `start` is only assigned before the first loop? – Keppil Aug 11 '14 at 07:20
  • @Keppil Ouch. You are right. Stupid error. – Timuçin Aug 11 '14 at 07:24
  • in your code you only have 1 start(time), for example if you start at 0 Long sum get exacuted and took 5905 millisecond and you did not set the start(time) the long sum2's time will be (Long sum + long sum2) so to get the long sum2's time (end-start-Long sum(time)). so long sum2 probably is 1108 – Ker p pag Aug 11 '14 at 07:24
  • to me the author is correct, sum += i where sum is Long requires autoboxing and converting it back to primitive .. back and forth. I would expect this to be slower than using only primitive type. – LeTex Aug 11 '14 at 07:25

1 Answers1

10

You didn't reset the starting point for the second measurement. The primitive performance is actually the time difference of your two values (which is obviously better than the wrapper's). Try this:

// Hideously slow program! Can you spot the object creation?
Long sum = 0L;
start = System.currentTimeMillis();
for (long i = 0; i < Integer.MAX_VALUE; i++) {
    sum += i;
}
end = System.currentTimeMillis();
System.out.println("Long sum took: " + (end - start) + " milliseconds");

long sum2 = 0L;

// reset start!!
start = System.currentTimeMillis();

for (long i = 0; i < Integer.MAX_VALUE; i++) {
    sum2 += i;
}
end = System.currentTimeMillis();
System.out.println("long sum took: " + (end - start) + " milliseconds");
webuster
  • 2,490
  • 18
  • 27