Is this a useful optimization for loops in java?

consider the following:

1.

for (final Bar a : bars) { for (final Foo f : foos) { doSomethingWith(f.foo(), a.bar()); } } 

and:

2.

  for (final Bar a : bars) { final Object bar = a.bar(); for (final Foo f : foos) { doSomethingWith(f.foo(), bar); } } 

Is such optimization really useful, or will the compiler do it automatically?

Will your answer change if bar () was a getter? (e.g. getBar ())

Will your answer change if I am set to develop Android?

+5
source share
3 answers

I tried two examples of how you are doing for your question. Based on this, I must say that the second approach will be better. ( Although I do not consider Multi-Threading )

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); } } } 

after compiling and then decompiling again I got this.

  * 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); } } } 

after compiling and then decompiling again I got this.

 /* * 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. } } } } 
+2
source

surprisingly, that might seem like an attempt:

 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()); } 

just a little tweak try

0
source

After looking at the comments and answering them, I realized that even if the compiler plunges into the understanding of the a.bar() code, it would be impossible to guarantee that the result of a.bar() will not change in a multi-threaded environment, such as in java, also in in combination with Reflection, if bar is a member field, it can be changed using reflections, and the compiler did not know what in advance, which could lead to unpredictability of a simple return bar; .

So at the moment, it seems reasonable to me that I continue to use this optimization in my code.

-2
source

All Articles