Java基准 - 为什么第二个循环更快?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (11)

我对此很好奇。

我想检查哪个函数更快,所以我创建了一个小代码并执行了很多次。

public static void main(String[] args) {

        long ts;
        String c = "sgfrt34tdfg34";

        ts = System.currentTimeMillis();
        for (int k = 0; k < 10000000; k++) {
            c.getBytes();
        }
        System.out.println("t1->" + (System.currentTimeMillis() - ts));

        ts = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            Bytes.toBytes(c);
        }
        System.out.println("t2->" + (System.currentTimeMillis() - ts));

    }

“second”循环更快,所以,我认为hadoop的Bytes类比String类的函数更快。然后,我改变了循环的顺序,然后c.getBytes()变得更快。我执行了很多次,我的结论是,我不知道为什么,但是在执行第一个代码后,我的虚拟机中发生了一些事情,以便第二个循环的结果变得更快。

提问于
用户回答回答于

这是一个经典的java基准测试问题。Hotspot / JIT / etc会在你使用它的时候编译你的代码,所以在运行的时候它会变得更快。

首先运行循环至少3000次(服务器上或64位上的10000次) - 然后进行测量。

用户回答回答于

你知道有什么问题,因为内部Bytes.toBytes调用c.getBytes

public static byte[] toBytes(String s) {
    try {
        return s.getBytes(HConstants.UTF8_ENCODING);
    } catch (UnsupportedEncodingException e) {
        LOG.error("UTF-8 not supported?", e);
        return null;
    }
}

源从这里被拿走。这告诉你,这个调用不可能比直接调用更快 - 在最好的情况下,它将具有相同的时间。不过,一般来说,由于调用一个函数的开销很小,所以你会期望它稍微慢一些。

这是在解释的垃圾收集环境中使用微型基准测试的经典问题,其中组件在任意时间运行,例如垃圾收集器。最重要的是,硬件优化(如缓存)会使图片偏斜。因此,查看发生的最好方法通常是查看来源。

扫码关注云+社区