3

我有两个相同大小的数组和两种方法。

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()装箱和拆箱比不拆箱快 10 倍primitiveToObject()

4

1 回答 1

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 对此进行了测试,并观察到了类似的结果。

于 2013-03-23T12:54:26.497 回答