在什么时候定义变量比制作方法调用更有效?

时间:2013-03-25 03:53:16

标签: java android performance optimization

我正在阅读Google's tips on Android optimisation,他们提出的第一点是你应该避免使用短期变量,因为这意味着更多的垃圾收集。 那么,有没有一点你最好定义一个变量并使用它而不是每次想要使用该对象时调用一个访问器?说,这个:

for(int i = 0; i < 1000; i++) {
    foo.getBar() // then do something with it
}

与此相反:

Bar bar = foo.getBar();
for(int i = 0; i < 1000; i++) {
    bar // then do something with it
}

有什么不同,表现明智?

3 个答案:

答案 0 :(得分:2)

从您提供的链接:“您应该避免创建不需要的对象实例”

  1. 对象实例!=短期变量
  2. 不要忘记句子的第二部分......
  3. 局部变量通常是allocated on the stack(GC无关紧要),而新的对象实例将在堆上分配 - 这是一个完全不同的故事。 TMHO说“如果你真的不需要,就不做某事”这样的东西没什么价值。此外,尽量避免在可能的情况下创建局部变量可能会对您的代码造成严重影响,read this

答案 1 :(得分:1)

假设没有编译器优化

使用时

for(int i = 0; i < 1000; i++) {
    foo.getBar() // then do something with it
}

您的代码将转到foo引用的实例,执行其getBar()方法,然后返回应该返回的实例/值。这将针对该循环的1000次执行中的每一次执行。每次执行完毕后,getBar()返回的值必须进行垃圾回收。

但是,当你使用:

Bar bar = foo.getBar();
for(int i = 0; i < 1000; i++) {
    bar // then do something with it
}

在循环之外只能获得foo.getBar()的值一次,并在本地存储它的副本。然后在循环中使用此本地副本1000次。

第二个选项更有效,因为foo实例的getBar()方法只调用一次,而不是一千次。这意味着您不会在getBar()方法中执行1000次代码,这显然比执行一次更糟糕。

这些都是微观优化。除非你在getBar()中做了一些真正繁重的工作,否则这不会产生明显的影响。在很多情况下,编译器优化会将这两者都变成完全相同的字节码,所以你不用担心它。

答案 2 :(得分:1)

在这个例子中,假设bar只是getBar返回的一个对象而没有创建,那么就GC而言没有区别。

但是,方法调用的开销也很小,第二个例子效率更高。

但是,如果getBar在每次调用时都创建了一个新对象,那么在第二个示例中将创建1000个新的Bars然后GCed,而第一个示例保持不变。