JDK是否对自己的api进行了一些优化?

时间:2013-03-05 01:35:49

标签: api arraylist jvm java

大家好,我已将java.util包中的ArrayList源代码复制到我自己的包中。但是我发现它比原始的java.util.ArrayList运行得更好。

测试代码:

@Test
public void jdkApiPerformance() {
    long startTime = System.nanoTime();
    java.util.ArrayList<Object> list = new java.util.ArrayList<Object>();
    long costTime = System.nanoTime() - startTime;
    System.out.println("jdkPerformance cost " + costTime + "ns.");
}

@Test
public void myApiPerformance() {
    long startTime = System.nanoTime();
    question.jdk.ArrayList<Object> list = new question.jdk.ArrayList<Object>();
    long costTime = System.nanoTime() - startTime;
    System.out.println("apiPerformance cost " + costTime + "ns.");
}

此测试的输出为打击:

jdkPerformance cost 10263ns.
apiPerformance cost 1244158ns.

显然,我的api运行速度比JDK api慢。

然后我为此测试添加了@Before方法:

@Before
public void setUp() {
    new java.util.ArrayList<Object>();
    new question.jdk.ArrayList<Object>();
}

此案例的输出已更改:

jdkPerformance cost 9932ns.
apiPerformance cost 1324ns.

我的api跑得比JDK api快!!

我对这种情况感到很困惑。请帮助我。谢谢。

2 个答案:

答案 0 :(得分:2)

1)使用System.nanoTime()可能会给您带来扭曲的结果,因为它取决于操作系统的调度程序粒度:

  

此方法提供纳秒级精度,但不一定是纳秒级分辨率(即值的变化频率) - 除了分辨率至少与currentTimeMillis()的分辨率一样好之外,不做任何保证。

2)要有有意义的基准,你必须先预热 JVM

3)对于研究,你可以使用一个基准测试库:

4)一般来说,你的问题的答案是:,在某些情况下,Sun / Oracle的JVM热替换一些JDK代码,例如Math.sqrt(),并针对给定的OS优化了实现硬件

答案 1 :(得分:1)

  • JVM按需加载类。由于java.util.ArrayList是这样一个基础类,它可能已经在您的基准测试开始之前加载,但是question.jdkArrayList可能是第一次使用。这涉及读取类文件的磁盘I / O,这本身比创建新实例花费的时间要多几个数量级。此外,Java.util.ArrayList更有可能由JIT编译器进行优化。

  • 根据其javadoc,System.nanoTime()具有“纳秒级精度,但不一定是纳秒精度”。用它来测量微秒级的延迟就是充其量。此外,它还可以测量挂钟时间,而不是CPU时间。如果您的cpu被占用(例如,在开发环境中绘制控制台视图),将计入报告的时间。

相关问题