[picocontainer-dev] RE: [picocontainer-scm] [4525] java/2.x/trunk/pico/container/src/test/org/picocontainer/defaults: constructor injection speedup : remembers (optionally) the constructor to use

"Michael Rimov" <[email protected]>
Newsgroups gmane.comp.java.picocontainer.devel
Organization Centerline Computers, Inc
Message-ID <00b801c8c205$638c1910$2aa44b30$@com>
Silly question:  is there a reason why you wouldn’t want to remember the constructor to use?  I can only think of memory resources, but if we did SoftReferences, we probably could strike a happy medium and save all the if/else clauses.

 

                                                                                                                                -Mike

 

 

From: paul-yCVjj/[email protected] [mailto:paul-yCVjj/[email protected]] 
Sent: Thursday, May 29, 2008 7:39 PM
To: scm-qxt/[email protected]
Subject: [picocontainer-scm] [4525] java/2.x/trunk/pico/container/src/test/org/picocontainer/defaults: constructor injection speedup : remembers (optionally) the constructor to use

 

Revision

4525 <http://fisheye.codehaus.org/changelog/picocontainer/?cs=4525> 

Author

paul

Date

2008-05-29 21:39:06 -0500 (Thu, 29 May 2008)


Log Message


constructor injection speedup : remembers (optionally) the constructor to use


Modified Paths


*	java/2.x/trunk/pico/container/src/java/org/picocontainer/injectors/ConstructorInjector.java <> 
*	java/2.x/trunk/pico/container/src/test/org/picocontainer/defaults/PicoExceptionsTestCase.java <> 
*	java/2.x/trunk/pico/container/src/test/org/picocontainer/injectors/AdaptingInjectionTestCase.java <> 
*	java/2.x/trunk/pico/container/src/test/org/picocontainer/injectors/ConstructorInjectorTestCase.java <> 


Diff


Modified: java/2.x/trunk/pico/container/src/java/org/picocontainer/injectors/ConstructorInjector.java (4524 => 4525)

 

--- java/2.x/trunk/pico/container/src/java/org/picocontainer/injectors/ConstructorInjector.java        2008-05-29 18:25:08 UTC (rev 4524)

+++ java/2.x/trunk/pico/container/src/java/org/picocontainer/injectors/ConstructorInjector.java        2008-05-30 02:39:06 UTC (rev 4525)

@@ -47,12 +47,13 @@

     /**

         * Serialization UUID.

         */

-       private static final long serialVersionUID = 3663020107106785481L;

+    private static final long serialVersionUID = 3663020107106785481L;

        

        private transient List<Constructor<T>> sortedMatchingConstructors;

     private transient ThreadLocalCyclicDependencyGuard<T> instantiationGuard;

-    

-    

+    private boolean rememberChosenConstructor = true;

+    private transient Constructor<T> chosenConstructor;

+

     /**

      * Constructor injector that uses no monitor and no lifecycle adapter.  This is a more

      * convenient constructor for use when instantiating a constructor injector directly.

@@ -82,6 +83,26 @@

         super(componentKey, componentImplementation, parameters, monitor, lifecycleStrategy, useNames);

     }

 

+    /**

+     * Creates a ConstructorInjector

+     *

+     * @param componentKey            the search key for this implementation

+     * @param componentImplementation the concrete implementation

+     * @param parameters              the parameters to use for the initialization

+     * @param monitor                 the component monitor used by this addAdapter

+     * @param lifecycleStrategy       the component lifecycle strategy used by this addAdapter

+     * @param useNames                use argument names when looking up dependencies

+     * @param rememberChosenCtor      remember the chosen constructor (to speed up second/subsequent calls)

+     * @throws org.picocontainer.injectors.AbstractInjector.NotConcreteRegistrationException

+     *                              if the implementation is not a concrete class.

+     * @throws NullPointerException if one of the parameters is <code>null</code>

+     */

+    public ConstructorInjector(final Object componentKey, final Class componentImplementation, Parameter[] parameters, ComponentMonitor monitor,

+                               LifecycleStrategy lifecycleStrategy, boolean useNames, boolean rememberChosenCtor) throws  NotConcreteRegistrationException {

+        super(componentKey, componentImplementation, parameters, monitor, lifecycleStrategy, useNames);

+        this.rememberChosenConstructor = rememberChosenCtor;

+    }

+

     protected Constructor<T> getGreediestSatisfiableConstructor(PicoContainer container) throws PicoCompositionException {

         final Set<Constructor> conflicts = new HashSet<Constructor>();

         final Set<List<Class>> unsatisfiableDependencyTypes = new HashSet<List<Class>>();

@@ -145,34 +166,42 @@

         return greediestConstructor;

     }

 

-

     public T getComponentInstance(final PicoContainer container, Type into) throws PicoCompositionException {

         if (instantiationGuard == null) {

             instantiationGuard = new ThreadLocalCyclicDependencyGuard<T>() {

                 public T run() {

-                    Constructor<T> constructor;

+                    Constructor<T> ctor = null;

                     try {

-                        constructor = getGreediestSatisfiableConstructor(guardedContainer);

+                        if (chosenConstructor == null) {

+                            ctor = getGreediestSatisfiableConstructor(guardedContainer);

+                        }

+                        if (rememberChosenConstructor) {

+                            if (chosenConstructor == null) {

+                                chosenConstructor = ctor;

+                            } else {

+                                ctor = chosenConstructor;

+                            }

+                        }

                     } catch (AmbiguousComponentResolutionException e) {

                         e.setComponent(getComponentImplementation());

                         throw e;

                     }

                     ComponentMonitor componentMonitor = currentMonitor();

                     try {

-                        Object[] parameters = getMemberArguments(guardedContainer, constructor);

-                        constructor = componentMonitor.instantiating(container, ConstructorInjector.this, constructor);

-                        if(constructor == null) {

+                        Object[] parameters = getMemberArguments(guardedContainer, ctor);

+                        ctor = componentMonitor.instantiating(container, ConstructorInjector.this, ctor);

+                        if(ctor == null) {

                             throw new NullPointerException("Component Monitor " + componentMonitor 

-                                            + " returned a null constructor from method 'instantiating' after passing in " + constructor);

+                                            + " returned a null constructor from method 'instantiating' after passing in " + ctor);

                         }

                         long startTime = System.currentTimeMillis();

-                        T inst = instantiate(constructor, parameters);

+                        T inst = instantiate(ctor, parameters);

                         componentMonitor.instantiated(container,

                                                       ConstructorInjector.this,

-                                                      constructor, inst, parameters, System.currentTimeMillis() - startTime);

+                                ctor, inst, parameters, System.currentTimeMillis() - startTime);

                         return inst;

                     } catch (InvocationTargetException e) {

-                        componentMonitor.instantiationFailed(container, ConstructorInjector.this, constructor, e);

+                        componentMonitor.instantiationFailed(container, ConstructorInjector.this, ctor, e);

                         if (e.getTargetException() instanceof RuntimeException) {

                             throw (RuntimeException) e.getTargetException();

                         } else if (e.getTargetException() instanceof Error) {

@@ -180,9 +209,9 @@

                         }

                         throw new PicoCompositionException(e.getTargetException());

                     } catch (InstantiationException e) {

-                        return caughtInstantiationException(componentMonitor, constructor, e, container);

+                        return caughtInstantiationException(componentMonitor, ctor, e, container);

                     } catch (IllegalAccessException e) {

-                        return caughtIllegalAccessException(componentMonitor, constructor, e, container);

+                        return caughtIllegalAccessException(componentMonitor, ctor, e, container);

 

                     }

                 }

Modified: java/2.x/trunk/pico/container/src/test/org/picocontainer/defaults/PicoExceptionsTestCase.java (4524 => 4525)

 

--- java/2.x/trunk/pico/container/src/test/org/picocontainer/defaults/PicoExceptionsTestCase.java        2008-05-29 18:25:08 UTC (rev 4524)

+++ java/2.x/trunk/pico/container/src/test/org/picocontainer/defaults/PicoExceptionsTestCase.java        2008-05-30 02:39:06 UTC (rev 4525)

@@ -43,7 +43,7 @@

     @SuppressWarnings({ "unchecked" })

     final void executeTestOfStandardException(final Class clazz) {

         final ComponentAdapter componentAdapter = new ConstructorInjector(clazz, clazz, null, new AbstractComponentMonitor(),

-                                                                          new NullLifecycleStrategy(), false);

+                                                                          new NullLifecycleStrategy(), false, false);

         DefaultPicoContainer pico = new DefaultPicoContainer();

         pico.addComponent(MESSAGE);

         try {

Modified: java/2.x/trunk/pico/container/src/test/org/picocontainer/injectors/AdaptingInjectionTestCase.java (4524 => 4525)

 

--- java/2.x/trunk/pico/container/src/test/org/picocontainer/injectors/AdaptingInjectionTestCase.java        2008-05-29 18:25:08 UTC (rev 4524)

+++ java/2.x/trunk/pico/container/src/test/org/picocontainer/injectors/AdaptingInjectionTestCase.java        2008-05-30 02:39:06 UTC (rev 4525)

@@ -119,6 +119,7 @@

         String foo = xs.toXML(ca).replace("\"", "");

 

         assertEquals("<Constructor-Injection>\n" +

+                     "  <rememberChosenConstructor>true</rememberChosenConstructor>\n" +

                      "  <lifecycleStrategy class=RLS/>\n" +

                      "  <useNames>false</useNames>\n" +

                      "  <componentKey class=java-class>java.util.Map</componentKey>\n" +

Modified: java/2.x/trunk/pico/container/src/test/org/picocontainer/injectors/ConstructorInjectorTestCase.java (4524 => 4525)

 

--- java/2.x/trunk/pico/container/src/test/org/picocontainer/injectors/ConstructorInjectorTestCase.java        2008-05-29 18:25:08 UTC (rev 4524)

+++ java/2.x/trunk/pico/container/src/test/org/picocontainer/injectors/ConstructorInjectorTestCase.java        2008-05-30 02:39:06 UTC (rev 4525)

@@ -373,4 +373,53 @@

         cica.dispose(touchable);

         assertEquals("<start<stop<dispose", strategy.recording());

     }

+

+    public static class One {

+        public One(Two two) {

+            two.inc();

+        }

+    }

+    public static class Two {

+        private int inc;

+        public void inc() {

+            inc++;

+        }

+

+        public long howMany() {

+            return inc;

+        }

+    }

+

+    @Test public void testSpeedOfRememberedConstructor()  {

+        long with, without;

+        timeIt(); // discard

+        timeIt(); // discard

+        timeIt(); // discard

+        rememberChosenCtor = false;

+        without = timeIt();

+        rememberChosenCtor = true;

+        with = timeIt();

+        System.out.println("-->testSpeedOfRememberedConstructor(): durations:" + with + " " + without);

+        assertTrue("with should be < without but were " + with + " and " + without, with < without);

+    }

+

+    boolean rememberChosenCtor;

+    private long timeIt() {

+        int iterations = 20000;

+        long with;

+        DefaultPicoContainer dpc = new DefaultPicoContainer();

+        Two two = new Two();

+        dpc.addComponent(two);

+        dpc.addAdapter(new ConstructorInjector(One.class, One.class, null,

+                    new NullComponentMonitor(),

+                    new NullLifecycleStrategy(), false, rememberChosenCtor));

+        long start = System.currentTimeMillis();

+        for (int x = 0; x < iterations; x++) {

+                One one = dpc.getComponent(One.class);

+            }

+        long end = System.currentTimeMillis();

+        assertEquals(iterations, two.howMany());

+        return end-start;

+    }

+

 }

 

  _____  

To unsubscribe from this list please visit: 

http://xircles.codehaus.org/manage_email
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.