【问题标题】:methods in foreach and for loops in javajava中foreach和for循环中的方法
【发布时间】:2016-07-18 06:19:32
【问题描述】:

我的问题是关于使用 Android 编译器在 java 中进行优化。每次迭代都会调用下面的map.values(),还是Android编译器会对其进行优化。

LinkedHashMap<String, Object> map;

for (Object object : map.values())
{
   //do something with object
}

同样,这里是另一个例子。每次迭代都会调用 aList.size() 吗?

List<Object> aList;

for (int i = 0; i < aList.size(); i++)
{
    object = aList.get(i);
    //do something with i
}

毕竟,每次迭代都调用方法真的很重要吗? Map.values() 和 List.size() 有什么作用吗?

【问题讨论】:

  • 这是一个Java问题,与Android没有任何关系。
  • 我理解对这个问题的兴趣,但出于任何实际目的,我强烈建议在优化代码之前对其进行分析。
  • @PhilippReichart - 询问一种编码风格是否比另一种具有固有的性能优势是非常有意义的。此外,分析也有其局限性。如果您正在为 Android 编写代码,您的代码可能会在各种平台上运行,其中一些可能有 JIT 编译器,有一些没有,还有一些甚至还不存在。
  • @TedHopp 我同意。我只是想提醒人们不要过早优化,这通常比在这里或那里失去一个循环更糟糕。

标签: java android


【解决方案1】:

在第一个示例中,map.values() 将被评估一次。根据Section 14.4.2 of the Java Language Specification,相当于:

for (Iterator<Object> i = map.values().iterator(); i.hasNext(); ) {
    Object object = i.next();
    // do something with object
}

在第二个中,每次评估测试时都会调用aList.size()。为了可读性,最好将其编码为:

for (Object object : aList) {
    // do something with object
}

但是,根据Android docs,这会更慢。假设您没有更改循环内的列表大小,最快另一种方法是在循环之前拉出列表大小:

final int size = aList.size();
for (int i = 0; i < size; i++)
{
    object = aList.get(i);
    //do something with i
}

如果aList 恰好是ArrayList,这将大大加快(上面链接的Android 文档说是3 倍),但对于@987654331 可能会慢很多(可能慢很多) @。这完全取决于List 实现类aList 到底是一种什么样的。

【讨论】:

  • "Android docs" 是一个损坏的链接。这是新的:developer.android.com/training/articles/perf-tips.html#Loops。它对 Ted 关于最快循环的说法进行了一个小的修正——它对于没有 JIT 的设备来说不是最快的(“foreach”是最快的,并且“foreach”在有 JIT 的设备上与“Ted 的禁食循环”没有区别)。
  • @JustinCase - 感谢您追踪新位置(和新信息)。我已经更新了答案本身的链接。
猜你喜欢
  • 1970-01-01
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-21
  • 1970-01-01
  • 2020-08-10
相关资源
最近更新 更多