I have two array of the same size and two methods.
public class Client {
private static int[] ints;
private static final int COUNT = 10000000;
private static Integer[] integers;
public static void main(String[] args) {
Random rand = new Random();
integers = new Integer[COUNT];
for (int i = 0; i < integers.length; i++) {
integers[i] = rand.nextInt();
}
ints = new int[COUNT];
for (int i = 0; i < ints.length; i++) {
ints[i] = rand.nextInt();
}
primitiveToObject();
objectsToPrimitiveToObject();
}
public static void primitiveToObject() {
long start = new Date().getTime();
List<Integer> objects = new ArrayList<>(ints.length);
for (int i = 0; i < ints.length; i++) {
int value = ints[i] + 1;
objects.add(value); //Boxing
}
System.out.println("prim -> object = " + (new Date().getTime() - start));
}
public static void objectsToPrimitiveToObject() {
long start = new Date().getTime();
List<Integer> result= new ArrayList<>(integers.length);
for (int i = 0; i < integers.length; i++) {
int value = integers[i] + 1; //Unboxing
result.add(value); //Boxing
}
System.out.println("obj -> prim -> object = " + (new Date().getTime() - start));
}
}
Why objectsToPrimitiveToObject() with boxing and unboxing works 10x time faster than primitiveToObject() without unboxing?
I think it is an artefact of how you are benchmarking the code.
I have run the following benchmark using JVM 1.7.0_09 with -XX:+AggressiveOpts -XX:CompileThreshold=1:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Main {
static final int COUNT = 1000000;
static int[] ints = new int[COUNT];
static Integer[] integers = new Integer[COUNT];
static void primitiveToObject() {
List<Integer> objects = new ArrayList<Integer>(ints.length);
for (int i = 0; i < ints.length; i++) {
int value = ints[i] + 1;
objects.add(value); //boxing
}
}
static void objectsToPrimitiveToObject() {
List<Integer> result= new ArrayList<Integer>(integers.length);
for (int i = 0; i < integers.length; i++) {
int value = integers[i] + 1; //unboxing
result.add(value); //boxing
}
}
public static void main(String[] args) {
Random rand = new Random();
for (int i = 0; i < COUNT; ++i) {
int val = rand.nextInt();
ints[i] = val;
integers[i] = val;
}
for (int i = 0; i < 10; ++i) {
long start_p = System.currentTimeMillis();
for (int j = 0; j < 100; ++j) {
primitiveToObject();
}
long end_p = System.currentTimeMillis();
long start_o = System.currentTimeMillis();
for (int j = 0; j < 100; ++j) {
objectsToPrimitiveToObject();
}
long end_o = System.currentTimeMillis();
System.out.printf("p2o:%d o2p2o:%d\n", end_p - start_p, end_o - start_o);
}
}
}
The results were as follows:
p2o:2043 o2p2o:818
p2o:709 o2p2o:748
p2o:670 o2p2o:756
p2o:675 o2p2o:742
p2o:679 o2p2o:750
p2o:700 o2p2o:757
p2o:738 o2p2o:733
p2o:706 o2p2o:786
p2o:684 o2p2o:752
p2o:676 o2p2o:799
As you can see, after the initial warm-up, primitiveToObject() is faster, as one might expect from a method that's doing less work.
For completeness, I've also tested this using JDK 6, and observed similar results.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With