【问题标题】:For looping efficiency为了循环效率
【发布时间】:2011-06-29 14:54:23
【问题描述】:

我正在编写一个 Android 游戏并尽可能提高效率。

我知道for循环比foreach效率更高,但我想知道以下2项效率是否存在差异:

// itemsList is an ArrayList

int length = itemsList.size();            

for(int i=0; i < length; i++)
{
   // do stuff
}

VS

for(int i=0; i < itemsList.size(); i++)
{
   // do stuff
}

【问题讨论】:

  • 当你测量它时,你学到了什么?
  • 如果列表是 ArrayList,foreach 循环可能会稍微慢一些,但如果列表是 LinkedList,它可能会更快,因为对链表的索引访问很慢。无论列表的具体类型如何,foreach 循环(或显式使用迭代器)是循环的最佳构造。

标签: java android for-loop performance


【解决方案1】:

这取决于。从理论上讲,第一个会更快,因为第二个必须在每次迭代中进行函数调用。在实践中,这可以在很大程度上得到优化。大小可能会被缓存在对象中,这使您只剩下函数调用的开销(实际上为零)。 但如果有疑问,请选择第一个。不会慢的。

但总的来说,请记住:过早优化是万恶之源。

不要选择特定的解决方案,因为您认为它们可能快一纳秒。相反,编写好的、可靠的、最重要的是可读的代码。然后,优化真正的瓶颈。

【讨论】:

    【解决方案2】:

    为了限制一次性变量的作用域,仍然只调用一次size(),可以这样写

    for(int i=0, n = itemsList.size(); i < n; i++) {
       // do stuff
    }
    

    在两个备选方案之间进行选择时,请按以下顺序对其进行优先排序:

    1. 可重复性
    2. 可维护性
    3. 可理解性
    4. 清晰
    5. 可测试性
    6. 逻辑上
    7. 效率:-)

    【讨论】:

      【解决方案3】:

      如果您仅将列表用于读取,那么您应该使用它

      int length = itemsList.size();            
      for(int i=0; i < length; i++)
      {
         // do stuff
      }
      

      但如果您从列表中删除元素,则使用此方法

      for(int i=0; i < itemsList.size(); i++)
      {
         // do stuff
      }
      

      【讨论】:

        【解决方案4】:

        第一个效率更高,尽管只有 非常 勉强给出了一个好的编译器。

        除非您每秒执行数百万次循环,否则不会有任何明显的区别。

        原因:

        • 在第一种情况下,循环限制可能会缓存在寄存器中
        • 在第二种情况下,循环在每次迭代中执行额外的内存查找。这是因为循环不能保证每次迭代的大小都不会改变,所以需要不断检查内存值。从技术上讲,还有函数调用的开销,尽管一个体面的 JIT 编译器可能会通过内联完全优化这一点。

        【讨论】:

          【解决方案5】:

          如果你使用

          for(int i=0; i < itemsList.size(); i++)
           {
            // do stuff
           }
          

          您将始终调用 itemsList.size() 方法。所以,如果你把这个值存储在一个变量中,你会更快。并尝试使用最终变量;-)

          【讨论】:

            【解决方案6】:

            如果您执行第二种方式,itemsList.size() 每次都必须计算。

            如果itemsList 很大,可能需要一段时间

            【讨论】:

            • size 可能是预先计算的/微不足道的,以找出一个数组。所以开销只是方法调用的开销。其中,可能会被 JIT 编译器内联。
            猜你喜欢
            • 2013-04-18
            • 2013-09-04
            • 2014-03-08
            • 1970-01-01
            • 1970-01-01
            • 2015-10-08
            • 2012-03-29
            • 1970-01-01
            • 2014-09-02
            相关资源
            最近更新 更多