【发布时间】:2020-04-18 16:28:21
【问题描述】:
原来,我有这个代码:
import java.util.*;
public class sandbox {
public static void main(String[] args) {
HashSet<Integer> hashSet = new HashSet<>();
for (int i = 0; i < 100_000; i++) {
hashSet.add(i);
}
long start = System.currentTimeMillis();
for (int i = 0; i < 100_000; i++) {
for (Integer val : hashSet) {
if (val != -1) break;
}
hashSet.remove(i);
}
System.out.println("time: " + (System.currentTimeMillis() - start));
}
}
在我的计算机上运行嵌套的 for 循环大约需要 4 秒,我不明白为什么要花这么长时间。外部循环运行 100,000 次,内部 for 循环应该运行 1 次(因为 hashSet 的任何值都不会是 -1)并且从 HashSet 中删除一个项目是 O(1),所以应该有大约 200,000 次操作。如果一秒钟内通常有 100,000,000 次操作,那我的代码为什么需要 4s 才能运行?
另外,如果hashSet.remove(i);这一行被注释掉,代码只需要16ms。
如果内部的for循环被注释掉了(而不是hashSet.remove(i);),代码只需要8ms。
【问题讨论】:
-
我确认您的发现。我可以推测原因,但希望聪明的人会发表一个有趣的解释。
-
看起来
for val循环是占用时间的事情。remove仍然非常快。修改集合后设置新迭代器的某种开销...? -
@apangin 在stackoverflow.com/a/59522575/108326 中很好地解释了为什么
for val循环很慢。但是,请注意,根本不需要循环。如果要检查集合中是否有任何不同于-1的值,检查hashSet.size() > 1 || !hashSet.contains(-1)会效率更高。
标签: java performance for-loop hashset