当它为null时,哪种设置方式更快?

时间:2011-07-21 19:08:43

标签: java performance optimization

Java中哪个更快,为什么?

try {
  object.doSomething()
} catch (NullPointerException e) {
  if (object == null) {
    object = new .....;
    object.doSomething();
  } else throw e;
}

if (object == null) {
  object = new .....;
}
object.doSomething();

为什么?

代码会经常被调用,object在第一次被调用时只有null,所以不要将抛出的NPE的成本考虑在内(它只会发生一次)。

P.S。我知道第二个更好,因为简单,可读性等,而且我肯定会在真实软件中使用。我知道所有关于过早优化的邪恶,不需要提及它。 我只是对这些小细节感到好奇。

7 个答案:

答案 0 :(得分:9)

你应该绝对使用后一种方式,不是因为它更快,而是因为它更具惯用性。 的例外应该用于java程序中的控制流。

这纯粹是轶事,但我所做过的所有微基准测试都表明,使用控制流的异常不会像条件一样高效,尽管可能不可能将此作为泛化支持,而JVM非常擅长无论如何,围绕这样的事情进行优化,所以YMMV。

答案 1 :(得分:2)

忘记速度 - 查看第一个代码段与第二个代码段中代码的大小。

更简单的选项是最好的吗?最容易阅读,占用更少的空间等。您应该首先争取代码简单性,然后在测量速度很慢时担心速度。

此外,考虑运行时需要做什么才能确定它需要抛出NullPointerException - 它必须检查当前引用是否为null。因此,即使没有测量,逻辑上有理由自己执行检查更简单,而不是将其留给JRE进行检查创建NullPointerException 和< / em>展开堆栈。

答案 2 :(得分:2)

无论速度如何,第一种方式都不是良好的编程习惯。例如,如果object不为空但object.doSomething()导致NullPointerException会怎么样?

这就是为什么你不应该使用异常来控制程序流的一个原因!

答案 3 :(得分:1)

要回答你的问题,版本1在爆炸时要慢得多,因为创建异常非常昂贵,但它并不比版本2快,因为JVM必须自己进行空检查无论如何所以你'不随时保存。编译器可能会优化代码,因此无论如何都不会更快。

此外,例外情况应保留例外情况。初始状态为null并不例外。

使用延迟初始化模式:

SomeClass getIt() {
    if (it == null)
        it = new SomeClass();
    return it;
}

...
getIt().someMethod();

答案 4 :(得分:1)

答案 5 :(得分:0)

抛出异常(第一个示例)几乎总是比正常控制流代码慢(第二个示例)

除了第二个更清晰,更容易理解

答案 6 :(得分:0)

我要说第二种解决方案更快。不是因为我是JIT或VM的专家,而是因为单个分支 - 如果相等的汇编级例程比在内存中查找对象更快,确定它是空的(相同的测试,我假设),抛出一个异常并可能弄乱堆栈。