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。我知道第二个更好,因为简单,可读性等,而且我肯定会在真实软件中使用。我知道所有关于过早优化的邪恶,不需要提及它。 我只是对这些小细节感到好奇。
答案 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的专家,而是因为单个分支 - 如果相等的汇编级例程比在内存中查找对象更快,确定它是空的(相同的测试,我假设),抛出一个异常并可能弄乱堆栈。