The below program is a typical Java trap, and also a popular Java interview question. It has no compiler error or warning but running very slow.
Can you spot the problem?
JavaSum.java
package com.mkyong;
import java.time.Duration;
import java.time.Instant;
public class JavaSum {
public static void main(String[] args) {
Instant start = Instant.now();
Long total = 0L;
for (long l = 0; l < Integer.MAX_VALUE; l++) {
total += l;
}
Instant end = Instant.now();
System.out.println(Duration.between(start, end).getSeconds() + " seconds");
System.out.println("Total: " + total);
}
}
Output
6 seconds
Total: 2305843005992468481
P.S The elapsed time may vary.
. (Scroll down for answer)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Answer
The mixed-used of primitive type and boxed primitive type (wrapper class), the boxed primitive type will auto-unboxed (Long -> long). In the above example, the Long total variable is repeatedly boxed and unboxed, causing the slow running of the program.
// Long -> unboxed -> long
// long -> boxed -> Long
Long total = 0L; // boxed primitive type (wrapper class)
for (long l = 0; l < Integer.MAX_VALUE; l++) { // here is primitive type!
// Long = Long (unboxed) -> long + long
// Long = (boxed) long
total += l;
}
To make it faster, update the Long total to long total:
long total = 0L;
for (long l = 0; l < Integer.MAX_VALUE; l++) {
total += l; // no more boxed and unboxed, and it run much faster!
}
Back to basic:
- Autoboxing –
int->Integer,long->Long, convertlongprimitive type to boxed primitive type (wrapper class)Long. - Unboxing –
Integer->int,Long->long, convertLongboxed primitive type (wrapper class) to primitive typelong.
| Primitive type | Wrapper class |
|---|---|
| boolean | Boolean |
| byte | Byte |
| char | Character |
| float | Float |
| int | Integer |
| long | Long |
| short | Short |
| double | Double |
Hi Mkyong,
thanks for your great tutorials!
It would be great if you would add the duration of your “non more box- and unboxing”
example for comparison of both cases 🙂
best regards!