How expensive is dynamic binding
I wrote a quick test harness to test how expensive dynamic versus compile time binding is in Java.
In my local environment, I got this result:
Calling Wombat.class.newInstance() 1000000 times took 218 milliseconds. Calling Class.forName("Wombat").newInstance() 1000000 times took 2047 milliseconds. Calling new Wombat() 1000000 times took 31 milliseconds. Storing to and reading from the state map 1000000 times took 157 milliseconds.
import java.util.Collections; import java.util.HashMap; import java.util.Map; import junit.framework.TestCase; public class TestPerformance extends TestCase { private static final int HOW_MANY = 1000000; private static final Map stateMap = Collections.synchronizedMap(new HashMap()); public void testInstantiation(){ long before = System.currentTimeMillis(); for (int i = 1; i < HOW_MANY; i++) { try { Wombat myWombat = (Wombat) Wombat.class.newInstance(); } catch (InstantiationException ie) { System.out.println("Do anything with the exception to ensure this block isn't optimized away."); } catch (IllegalAccessException e) { System.out.println("Do anything with the exception to ensure this block isn't optimized away."); } } long after = System.currentTimeMillis(); long elapsedTime = after - before; System.out.println("Calling Wombat.class.newInstance() " + HOW_MANY + " times took " + elapsedTime + " milliseconds."); } public void testInstantiationWithClassForname() { long before = System.currentTimeMillis(); for (int i = 1; i < HOW_MANY; i++) { try { Wombat myWombat = (Wombat) Class.forName("Wombat").newInstance(); } catch (InstantiationException ie) { System.out.println("Do anything with the exception to ensure this block isn't optimized away."); } catch (IllegalAccessException e) { System.out.println("Do anything with the exception to ensure this block isn't optimized away."); } catch (ClassNotFoundException e) { System.out.println("Do anything with the exception to ensure this block isn't optimized away."); } } long after = System.currentTimeMillis(); long elapsedTime = after - before; System.out.println("Calling Class.forName(\"Wombat\").newInstance() " + HOW_MANY + " times took " + elapsedTime + " milliseconds."); } public void testNew() { long before = System.currentTimeMillis(); for (int i = 1; i < HOW_MANY; i++) { Wombat myWombat = new Wombat(); } long after = System.currentTimeMillis(); long elapsedTime = after - before; System.out.println("Calling new Wombat() " + HOW_MANY + " times took " + elapsedTime + " milliseconds."); } public void testMapThrashing() { String[] keys = {"1", "2", "3"}; this.stateMap.put("1", new Wombat()); this.stateMap.put("2", new Wombat()); this.stateMap.put("3", new Wombat()); Wombat aWombat = new Wombat(); long before = System.currentTimeMillis(); for (int i = 1; i < HOW_MANY; i++) { this.stateMap.put("1", aWombat); Wombat myWombat = (Wombat) this.stateMap.get("1"); } long after = System.currentTimeMillis(); long elapsedTime = after - before; System.out.println("Storing to and reading from the state map " + HOW_MANY + " times took " + elapsedTime + " milliseconds."); } }