用于循环优化的Java - 在循环之前存储getter

时间:2013-04-18 18:38:48

标签: java performance for-loop compiler-optimization callstack

假设您有以下代码..

for(Element elm : elements)
   if(elm instanceof Foobar)
      Session.getSomething().getListOfSomething().add((Foobar)elm);

执行以下操作会不会更好?

List<Foobar> list = Session.getSomething().getListOfSomething();

for(Element elm : elements)
   if(elm instanceof Foobar)
      list.add((Foobar)elm);

假设在执行循环期间Something和listOfSomething不会改变。 我认为这可以大大减少因减少方法调用而产生的callstack push / pops数量。

这种优化是不是太挑剔了?我不认为java编译器会认为他们可以这样优化。

编辑:未简化代码以排除AddAll的使用

2 个答案:

答案 0 :(得分:1)

在大多数情况下会更好。原因是Java对调用约定非常严格,并且对于每次迭代,它都必须进行4次额外的虚拟调用。有一些例外(即JIT内联),但这是一种异国情调。

虽然使用默认功能可能更好:

Session.getSomething().getListOfSomething().addAll(elements)

答案 1 :(得分:0)

这将取决于getSomething()getListOfSomething()做什么。它可能没有被优化的原因是编译器不知道调用是否每次都返回相同的东西,或者是否存在调用这些方法的其他副作用。如果它确实每次都返回相同的东西,没有副作用,那么它是一个优化,如果不是那么它就不再是同一个程序。