考虑以下事项:
1
for (final Bar a : bars) {
for (final Foo f : foos) {
doSomethingWith(f.foo(), a.bar());
}
}
和:
2
for (final Bar a : bars) {
final Object bar = a.bar();
for (final Foo f : foos) {
doSomethingWith(f.foo(), bar);
}
}
这种优化真的很有用吗?或者编译器会自动执行吗?
如果bar()是吸气剂,你的答案会改变吗? (例如getBar())
如果我定位Android开发,您的答案会改变吗?
答案 0 :(得分:1)
我根据你的问题尝试了两个例子。在此基础上,我必须说第二种方法会更好。 (虽然我不考虑多线程)
Test.java
public class Test{
public static void main(String... args){
String[][] arr2 = new String[5][5];
for (final String[] obj : arr2)
{
for (final String str : obj)
System.out.println(str.length() +" " + obj.length);
}
}
}
编译后再反编译我得到了这个。
* Decompiled with CFR 0_114.
*/
import java.io.PrintStream;
public class Test {
public static /* varargs */ void main(String ... arrstring) {
String[][] arrstring2;
String[][] arrstring3 = arrstring2 = new String[5][5];
int n = arrstring3.length;
for (int i = 0; i < n; ++i) {
String[] arrstring4;
for (String string : arrstring4 = arrstring3[i]) { //assignment will take place m*n.
System.out.println("" + string.length() + " " + arrstring4.length);
//this arrstring4.length will execute m*n (in this case).So, this will less efficient than others.
}
}
}
}
Test1.java
public class Test1{
public static void main(String... args){
String[][] arr2 = new String[5][5];
for (final String[] obj : arr2)
{
int value = obj.length;
for (final String str : obj)
System.out.println(str.length() +" " + value);
}
}
}
编译后再反编译我得到了这个。
/*
* Decompiled with CFR 0_114.
*/
import java.io.PrintStream;
public class Test1 {
public static /* varargs */ void main(String ... arrstring) {
String[][] arrstring2;
for (String[] arrstring3 : arrstring2 = new String[5][5]) {
int n = arrstring3.length; //Assignment will take place M times only.
//this will calculate M times only. So, it will definitely faster than above.
for (String string : arrstring3) {
System.out.println("" + string.length() + " " + n);
//here n is calculate M times but can be printed M*N times.
}
}
}
}
答案 1 :(得分:0)
令人惊讶,因为它可能会尝试:
for (final Bar a : bars) {
innerLoop(a, foos);
}
private final innerLoop(Bar a, Collection<Foo> foos) {
for (final Foo f : foos) {
doSomethingWith(f.foo(), a.bar());
}
只是一个小小的调整,试一试
答案 2 :(得分:-1)
在看到评论并不得不回答之后,我意识到即使编译器会深入理解a.bar()
的代码,也不可能保证a.bar()
结果不会改变。一个多线程的环境,比如它在java中,如果bar
是一个成员字段,它可以通过反射改变,并且编译器不会事先知道这可能会导致一个简单的{{1}无法预测。
目前,在我的代码中继续使用该优化似乎是合理的。