【问题标题】:Java for loop optimization - Storing getters before the loopJava for 循环优化 - 在循环之前存储 getter
【发布时间】:2013-04-12 00:33:30
【问题描述】:

假设你有以下代码..

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 在循环执行期间没有改变。 我认为由于方法调用减少,这可以大大减少调用堆栈推送/弹出的数量。

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

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

【问题讨论】:

  • 为什么不Session.getSomething().getListOfSomething().addAll(elements)
  • I don't think java compilers would assume they could optimize this way.,为什么?
  • 我很确定很多编译器确实假设他们可以这样优化。
  • @GuillermoRenéRamírez 不在 Java 中。仅当方法是最终方法并返回 const 值时。
  • @GuillermoRenéRamírez 这意味着它可以作为非虚拟函数调用,因此它是代码生成阶段内联的良好候选者。 IE。如果函数是最终的或私有的,或者整个类是最终的或私有的,编译器可以在不违反 Java 约定的情况下做出更多的假设

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


【解决方案1】:

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

虽然使用默认函数可能会更好:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2016-02-23
      • 1970-01-01
      • 2011-08-30
      • 1970-01-01
      • 1970-01-01
      • 2015-04-15
      • 2020-11-07
      • 2018-12-23
      • 2019-10-09
      相关资源
      最近更新 更多