我有两个相同大小的数组和两个方法。
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));
}
}
为什么objectsToPrimitiveToObject()
装箱和拆箱的速度比没有拆箱的primitiveToObject()
快10倍?
答案 0 :(得分:3)
我认为这是一个关于如何对代码进行基准测试的人工制品。
我使用JVM 1.7.0_09
与-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);
}
}
}
结果如下:
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
正如您所看到的,在最初的热身之后,primitiveToObject()
更快,正如人们可能期望从一种方法做得更少的工作。
为了完整性,我还使用JDK 6对其进行了测试,并观察到了类似的结果。