我刚刚看到这个看似无害的评论,对ArrayList和原始String数组进行基准测试.它来自几年前,但OP写道
我注意到使用String s:stringsList比使用旧式for循环访问列表慢约50%.去搞清楚...
没有人在原帖中评论它,测试看起来有点可疑(太短不准确),但是当我读到它时,我差点从椅子上掉下来.我从来没有对一个"传统"的循环增强循环进行基准测试,但我目前正在开发一个项目,它使用增强循环对ArrayList实例进行数亿次迭代,所以这是我关注的问题.
我打算做一些基准测试并在此发表我的发现,但这显然是我的一个大问题.我可以在网上找到关于相对性能的宝贵的小信息,除了一些随便提到的ArrayLists的增强循环在Android下运行速度慢得多.
有没有人经历过这个?这种性能差距是否仍然存在?我会在这里发布我的发现,但读到它时非常惊讶.我怀疑如果这个性能差距确实存在,它已经在更现代的VM中得到修复,但我想我现在必须做一些测试并确认.
更新:我对我的代码进行了一些更改,但是已经怀疑其他人已经指出的内容:确保增强的for循环速度较慢,但是在非常简单的紧密循环之外,成本应该是成本的一小部分.循环的逻辑.就我而言,即使我使用增强型循环迭代非常大的字符串列表,我在循环中的逻辑也足够复杂,甚至在切换到基于索引的循环之后我甚至无法测量差异.
TL; DR:增强循环确实比传统的基于索引的循环慢于arraylist; 但对于大多数应用来说,差异应该可以忽略不计.
您遇到的问题是使用Iterator比使用直接查找要慢.在我的机器上,每次迭代的差异大约为0.13 ns.使用数组代替每次迭代节省大约0.15 ns.在99%的情况下,这应该是微不足道的.
public static void main(String... args) {
int testLength = 100 * 1000 * 1000;
String[] stringArray = new String[testLength];
Arrays.fill(stringArray, "a");
List<String> stringList = new ArrayList<String>(Arrays.asList(stringArray));
{
long start = System.nanoTime();
long total = 0;
for (String str : stringArray) {
total += str.length();
}
System.out.printf("The for each Array loop time was %.2f ns total=%d%n", (double) (System.nanoTime() - start) / testLength, total);
}
{
long start = System.nanoTime();
long total = 0;
for (int i = 0, stringListSize = stringList.size(); i < stringListSize; i++) {
String str = stringList.get(i);
total += str.length();
}
System.out.printf("The for/get List loop time was %.2f ns total=%d%n", (double) (System.nanoTime() - start) / testLength, total);
}
{
long start = System.nanoTime();
long total = 0;
for (String str : stringList) {
total += str.length();
}
System.out.printf("The for each List loop time was %.2f ns total=%d%n", (double) (System.nanoTime() - start) / testLength, total);
}
}
Run Code Online (Sandbox Code Playgroud)
当以10亿个条目运行条目打印时(使用Java 6更新26)
The for each Array loop time was 0.76 ns total=1000000000
The for/get List loop time was 0.91 ns total=1000000000
The for each List loop time was 1.04 ns total=1000000000
Run Code Online (Sandbox Code Playgroud)
以10亿个条目运行时打印条目(使用OpenJDK 7)
The for each Array loop time was 0.76 ns total=1000000000
The for/get List loop time was 0.91 ns total=1000000000
The for each List loop time was 1.04 ns total=1000000000
Run Code Online (Sandbox Code Playgroud)
即完全相同.;)