JLS指出,对于数组,“增强的for语句相当于以下形式的基本 for 语句”。但是,如果我检查 JDK8 生成的字节码,对于两种变体都会生成不同的字节码,并且如果我尝试测量性能,令人惊讶的是,增强的字节码似乎给出了更好的结果(在 jdk8 上)...有人可以建议为什么吗? \是吗?我猜这是因为 jmh 测试不正确,所以如果是这样,请建议如何解决这个问题。(我知道 JMH 声明不要使用循环进行测试,但我认为这不适用于此处,因为我实际上是在尝试测量此处的循环)
\n我的 JMH 测试相当简单(可能太简单了),但我无法解释结果。测试JMH代码如下,典型结果为:
\nJdkBenchmarks.enhanced avgt 5 2556.281 \xc2\xb1 31.789 ns/op\nJdkBenchmarks.indexed avgt 5 4032.164 \xc2\xb1 100.121 ns/op\nRun Code Online (Sandbox Code Playgroud)\n这意味着通常增强的 for 循环速度更快,并且其测量比索引循环更准确,因此我们无法解决测量不确定性的差异。原则上,对于使用随机整数初始化的数组或更大的数组,结果相同。
\npublic class JdkBenchmarks {\n\n @Benchmark\n @BenchmarkMode(AverageTime)\n @OutputTimeUnit(NANOSECONDS)\n public void indexed(Blackhole blackhole, TestState testState) {\n int length = testState.values.length;\n for(int i = 0; i < length; i++) {\n blackhole.consume(testState.values[i]);\n }\n }\n\n @Benchmark\n @BenchmarkMode(AverageTime)\n @OutputTimeUnit(NANOSECONDS)\n public void enhanced(Blackhole blackhole, TestState testState) {\n for …Run Code Online (Sandbox Code Playgroud) List<T> list = new ArrayList<T>();
Run Code Online (Sandbox Code Playgroud)
1方法:
for(int i = list.length - 1; i >= 0; i--) {
System.out.println(list.get(i));
}
Run Code Online (Sandbox Code Playgroud)
2方法:
for(T t : list) {
System.out.println(t);
}
Run Code Online (Sandbox Code Playgroud)
3方法:
Iterator<T> it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
Run Code Online (Sandbox Code Playgroud) 在Java中,低于最快的解决方案:
public convert(ArrayList<Integer> IntegerList) {
int s = IntegerList.size();
int[] intArray = new int[s];
for (int i = 0; i < s; i++) {
intArray[i] = IntegerList.get(i).intValue();
}
}
Run Code Online (Sandbox Code Playgroud)
?
问题是,"我们可能期望method3比method2运行得更快,为什么会这样?" 但我不知道.似乎两种方法都执行相同数量的操作.有人可以赐教吗?
ArrayList<Person> method2(Person x, ArrayList<Person> people){
ArrayList<Person> friends = new ArrayList<Person>();
for (Person y : people) if (x.knows(y)) friends.add(y);
return friends;
}
ArrayList<Person> method3(Person x, ArrayList<Person> people){
ArrayList<Person> friends = new ArrayList<Person>();
for (int=0; i<people.size(); i++){
Person y = people.get(i);
if (x.knows(y)) friends.add(y);
}
return friends;
}
Run Code Online (Sandbox Code Playgroud) 我想知道使用方法调用作为获取集合的foreach参数的性能.让我们看看例子:
for (Entry<K, V> entry : map.entrySet()) {
doing.stuff();
}
Run Code Online (Sandbox Code Playgroud)
我想JVM在启动循环之前只调用一次map.entrySet(),取第一个元素,取他的迭代器并迭代它,再也不调用map.entrySet(),或者在数组的情况下只用本地创建迭代它int iterator(或者像那样),但我不知道JVM是如何工作的,所以我想确定 - 它是否以这种方式工作,或者更好地在循环之前保存集合并将其作为本地var传递,而不是调用内循环的吸气剂?
如果我们有两种迭代方式:
第一:
Object ob;
ArrayList<Obect> list;
for(int i=0;i<list.size();i++)
{ //Todo}
Run Code Online (Sandbox Code Playgroud)
第二:
Object ob;
ArrayList<Obect> list;
for(Object o:list)
{ //Todo}
Run Code Online (Sandbox Code Playgroud)
那有什么区别?我发现在第二种情况下,如果尝试在此循环中删除对象,我会得到并发修改异常.