创建对象会使VM更快吗?

时间:2009-09-27 19:13:51

标签: java algorithm optimization object creation

看看这段代码:

MessageParser parser = new MessageParser();
for (int i = 0; i < 10000; i++) {
    parser.parse(plainMessage, user);
}

出于某种原因,它比

运行SLOWER(大约100ms)
for (int i = 0; i < 10000; i++) {
    MessageParser parser = new MessageParser();
    parser.parse(plainMessage, user);
}

任何想法为什么?测试重复了很多次,所以它不仅仅是随机的。如何创建一个对象10000次比创建一次快?

4 个答案:

答案 0 :(得分:10)

因为Java具有“世代垃圾收集”并且可以快速识别(在循环中)它不会重复使用相同的对象/内存空间,因此GC成本几乎为零。另一方面,你的长寿对象将在托儿所世代传承下来,并且必须搬到主要世代。

总之,如果不进行测试来测量它,就无法真正假设性能。

答案 1 :(得分:0)

在后续调用解析器时可能会有一些逻辑来清理内部状态。

GC是否在您的基准测试期间运行?实例化一个新对象相当便宜,如果你不计算处理你在更快的情况下创建的所有对象的时间,这不是一个公平的比较。

答案 2 :(得分:0)

我不知道MessageParser做了什么或来自哪里。它可能在内部“泄漏”。另一种可能性是对象变得远离解析期间创建的数据。这意味着您可能会得到TLA未命中。此外,如果MessageParser保持内部状态,并进入终身代,那么注意它引用新数据的GC机制可能是一个问题(“卡片评分”是一种流行的术语)。

答案 3 :(得分:0)

如果您在限制parser的范围时对第一个示例进行基准测试会发生什么,即

{
    MessageParser parser = new MessageParser();
    for (int i = 0; i < 10000; i++) {
        parser.parse(plainMessage, user);
    }
}
// `parser` no longer visible

我希望这是最快的,因为只需要创建一个对象,并且VM仍然知道在循环之后可以立即执行parser