这是java中循环的有用优化吗?

时间:2016-05-16 11:19:55

标签: java android optimization

考虑以下事项:

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开发,您的答案会改变吗?

3 个答案:

答案 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}无法预测。

目前,在我的代码中继续使用该优化似乎是合理的。