Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The problem with conditions is, as you might know, that they cripple predictability features of processors. This means that a prefetch will actually turn into a disadvantage, if it is wrong. This is what happens in todays processors when they don't know what the result of a comparison might be, so they <strong>bet</strong>. In an IF-ELSE statement the processor has a 50% probability of correctly predicting the next instruction to be executed. If we are lucky we execute more instructions per cycle, if we are not, we get a medium of ~16 cycle penalty for the processor to recover from the wrong prefetching.</p> <p>That said let's go on to reflection. Reflection is mean, IF performance is important to you. In most frameworks reflection vs. address call is <code>C_reflection = 3*C_address_call</code>. In Java it is even worse and I don't really have official numbers about it. The biggest problem is name/address/availability resolution.</p> <p>That said, lets go to the real world and see some numbers. As we now can understand, justify and even predict results.</p> <p>We test 2 classes, 3 tests. For a total of 10M calls/test | 5M calls per class:</p> <ol> <li>Conditional</li> <li>Reflection</li> <li>Common Interface</li> </ol> <p>And these are the numbers in seconds:</p> <p>Conditions - 0.022333</p> <p>Reflection - <strong>3.02087</strong></p> <p>Interface - 0.012547</p> <p>So common interface is the winner in your case, second comes conditional call with almost double the execution time (for the reasons specified above). And last one with an extremely notable difference comes reflection.</p> <p>Here is the code of the test * :</p> <pre><code>import java.lang.reflect.InvocationTargetException; public class JavaReflectionTest { public interface ClassInterface { public void execute(); public String getCount(); } public static class ClassOne implements ClassInterface { int count = 0; public String getCount(){ return String.valueOf(count); } public void execute(){ count++; } } public static class ClassTwo implements ClassInterface { int count = 0; public String getCount(){ return String.valueOf(count); } public void execute(){ count++; } } public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, InterruptedException { ClassOne one = new ClassOne(); ClassTwo two = new ClassTwo(); ClassInterface ione = new ClassOne(); ClassInterface itwo = new ClassTwo(); long stopT; long startT; int i; int mod; //Warm up for(i=0;i&lt;350000;i++){ one.execute(); two.execute(); ione.execute(); itwo.execute(); one.getClass().getMethod("execute").invoke(one,null); two.getClass().getMethod("execute").invoke(two,null); } //Test conditional call one = new ClassOne(); two = new ClassTwo(); Thread.sleep(1000); startT=System.nanoTime(); for(i=0;i&lt;10000000;i++){ mod=i%2; if(mod==0) one.execute(); else two.execute(); } stopT=System.nanoTime(); System.out.println("Conditions - " + ((stopT-startT)/1000000000.0f)+ " Calls 1: " + one.getCount() + " Calls 2: " + two.getCount()); //Test reflection one = new ClassOne(); two = new ClassTwo(); Thread.sleep(1000); startT = System.nanoTime(); for(i=0;i&lt;5000000;i++){ mod=i%2; one.getClass().getMethod("execute").invoke(one,null); two.getClass().getMethod("execute").invoke(two,null); mod=i%2; } stopT=System.nanoTime(); System.out.println("Reflection - " + ((stopT-startT)/1000000000.0f)+ " Calls 1: " + one.getCount() + " Calls 2: " + two.getCount()); //Test common interface ione = new ClassOne(); itwo = new ClassTwo(); Thread.sleep(1000); startT = System.nanoTime(); for(i=0;i&lt;5000000;i++){ mod=i%2; ione.execute(); itwo.execute(); mod=i%2; } stopT=System.nanoTime(); System.out.println("Interface - " + ((stopT-startT)/1000000000.0f) + " Calls 1: " + ione.getCount() + " Calls 2: " + itwo.getCount()); } } </code></pre> <ul> <li>before creating performance tests we need to be sure that the compiler will optimize/modify our code as less as possible, this explains some of the statements in the test that you might not find intuitive.</li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload