Reputation: 1605
Why groups j=k*l
and m=n*o
have different performance, while first 3 groups have the same ?
int a = 42;
int b = 42;
int c = 42;
Integer d = 42;
int e = 42;
int f = 42;
int g = 42;
Integer h = 42;
int i = 42;
int j = 42;
int k = 42;
Integer l = 42;
Integer m = 42;
Integer n = 42;
Integer o = 42;
for(int z = 0; z < 1000000000; z++){
// c = a*b; // 630 ms
// f = d*e; // 630 ms
// i = g*h; // 630 ms
// l = j*k; // 6000 ms
// o = m*n; // 6400 ms
}
Upvotes: 6
Views: 2057
Reputation: 55609
Creating an object has an overhead (or, from other comments, it appears that it might be that, when creating an object, the loop can't optimised away because nothing is being done inside it).
int = int * int
No objects involved.
int = Integer * int
or int = int * Integer
The Integer's int member get multiplied with the int, and no objects need to be created.
Integer = int * int
An Integer object needs to be created from the result (slow).
Integer = Integer * Integer
The two Integer's int members get multiplied, but then an Integer object needs to be created from the result (slow).
Upvotes: 0
Reputation: 12924
Basically this is what happening inside JVM and thats causing performance issue.
c = a*b; // 630 ms -> No boxing and unboxing
f = d*e; // 630 ms -> Unboxing d
i = g*h; // 630 ms -> Unboxing h
l = j*k; // 6000 ms -> Creates a new Integer object L, and assign J * K to L
o = m*n; // 6400 ms -> Creates a new Integer object 0, unbox m and n for calculation and assign m * n to o
In other words
l = j*k; // 6000 ms is equivalent to below code
temp = j*k;
Integer l = new Integer(temp);
o = m*n; // 6400 ms is equivalent to below code
temp = j.intValue() * k.intValue();
Integer l = new Integer(temp);
Your last two statements will create around 1000000000
(loop count) unnecessary Integer
object. Which will be obviously a performance slog.
Upvotes: 4
Reputation: 533492
You have a loop which doesn't do anything useful. As such the JIT can take some time to detect this and eliminate the loop. In the first four examples, the code is taking an average of a fraction of a clock cycle. This is a strong hint that the loop has been optimised away and you are actually measuring how long it takes to detect and replace the loop with nothing,
In the later examples, the loop is not optimised away because there is something about the loop which the JIT doesn't eliminate. I suspected it was the object allocation for the Integer
but -verbosegc
showed that no objects were being created.
On my machine the loop take about 1.9 ns or about 6 clock cycles which is pretty quick so I am not sure what is left which takes that much time..
Upvotes: 6
Reputation: 4369
Creating a new object in a cycle always has a cost. In the last two examples you created new Integer objects in the cycle what has high performance cost. Primitives are stored in stack, objects are in heap. Putting something into stack is cheaper than into heap.
Upvotes: 4
Reputation: 7937
check this: java.lang.Integer.IntegerCache
Upvotes: 1
Reputation: 37566
m = n*o ==> Integer = Integer * Integer
while:
l = j*k ==> Integer = int * int // Integer is an object so autoboxing costs some performance here.
Upvotes: 0
Reputation: 691715
Probably because l = j * k
needs to box an int to an Integer, whereas c = a * b
doesn't need to. The VM could also optimize the loop, understanding that executing a single iteration would lead to the same result as executing 1 billion. Beware of simplistic micro-benchmarks.
Upvotes: 0