You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2012/03/02 19:28:12 UTC

svn commit: r1296363 - in /myfaces/core/trunk: api/src/main/java/javax/faces/component/ impl/src/main/java/org/apache/myfaces/component/visit/ impl/src/main/java/org/apache/myfaces/lifecycle/ impl/src/main/java/org/apache/myfaces/renderkit/html/ impl/s...

Author: lu4242
Date: Fri Mar  2 18:28:11 2012
New Revision: 1296363

URL: http://svn.apache.org/viewvc?rev=1296363&view=rev
Log:
MYFACES-3467 [PERF] Use index-based loop where possible - part II (Thanks to Martin Koci for provide this patch)

Modified:
    myfaces/core/trunk/api/src/main/java/javax/faces/component/UIComponentBase.java
    myfaces/core/trunk/api/src/main/java/javax/faces/component/UIData.java
    myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java
    myfaces/core/trunk/api/src/main/java/javax/faces/component/_ComponentChildrenList.java
    myfaces/core/trunk/api/src/main/java/javax/faces/component/_DeltaList.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/component/visit/PartialVisitContext.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlAjaxBehaviorRenderer.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlFormatRenderer.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
    myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java
    myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/util/ArrayUtils.java

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIComponentBase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIComponentBase.java?rev=1296363&r1=1296362&r2=1296363&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIComponentBase.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIComponentBase.java Fri Mar  2 18:28:11 2012
@@ -401,9 +401,10 @@ public abstract class UIComponentBase ex
             {
                 return;
             }
-            for (Iterator<FacesListener> it = _facesListeners.iterator(); it.hasNext();)
+            // perf: _facesListeners is RandomAccess instance (javax.faces.component._DeltaList)
+            for (int i = 0, size = _facesListeners.size(); i < size; i++)
             {
-                FacesListener facesListener = it.next();
+                FacesListener facesListener = _facesListeners.get(i);
                 if (event.isAppropriateListener(facesListener))
                 {
                     event.processListener(facesListener);
@@ -1164,9 +1165,10 @@ public abstract class UIComponentBase ex
             return (FacesListener[]) Array.newInstance(clazz, 0);
         }
         List<FacesListener> lst = null;
-        for (Iterator<FacesListener> it = _facesListeners.iterator(); it.hasNext();)
+        // perf: _facesListeners is RandomAccess instance (javax.faces.component._DeltaList)
+        for (int i = 0, size = _facesListeners.size(); i < size; i++)
         {
-            FacesListener facesListener = it.next();
+            FacesListener facesListener = _facesListeners.get(i);
             if (facesListener != null && clazz.isAssignableFrom(facesListener.getClass()))
             {
                 if (lst == null)
@@ -1670,9 +1672,12 @@ public abstract class UIComponentBase ex
         {
             if (ArrayList.class.equals(attachedObject.getClass()))
             {
-                List<Object> lst = new ArrayList<Object>(((List<?>) attachedObject).size());
-                for (Object item : (List<?>) attachedObject)
+                ArrayList<?> list = (ArrayList<?>) attachedObject;
+                int size = list.size();
+                List<Object> lst = new ArrayList<Object>(size);
+                for (int i = 0; i < size; i++)
                 {
+                    Object item = list.get(i);
                     if (item != null)
                     {
                         lst.add(saveAttachedState(context, item));
@@ -1715,10 +1720,12 @@ public abstract class UIComponentBase ex
         }
         if (stateObj instanceof _AttachedListStateWrapper)
         {
-            List<Object> lst = ((_AttachedListStateWrapper) stateObj).getWrappedStateList();
+            // perf: getWrappedStateList in _AttachedListStateWrapper is always ArrayList: see saveAttachedState
+            ArrayList<Object> lst = (ArrayList<Object>) ((_AttachedListStateWrapper) stateObj).getWrappedStateList();
             List<Object> restoredList = new ArrayList<Object>(lst.size());
-            for (Object item : lst)
+            for (int i = 0, size = lst.size(); i < size; i++)
             {
+                Object item = lst.get(i);
                 restoredList.add(restoreAttachedState(context, item));
             }
             return restoredList;

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIData.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIData.java?rev=1296363&r1=1296362&r2=1296363&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIData.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIData.java Fri Mar  2 18:28:11 2012
@@ -1667,9 +1667,12 @@ public class UIData extends UIComponentB
 
     private boolean hasErrorMessages(FacesContext context)
     {
-        for (Iterator<FacesMessage> iter = context.getMessages(); iter.hasNext();)
+        // perf: getMessageList() return a RandomAccess instance.
+        // See org.apache.myfaces.context.servlet.FacesContextImpl.addMessage
+        List<FacesMessage> messageList = context.getMessageList();
+        for (int i = 0, size = messageList.size(); i < size;  i++)
         {
-            FacesMessage message = iter.next();
+            FacesMessage message = messageList.get(i);
             if (FacesMessage.SEVERITY_ERROR.compareTo(message.getSeverity()) <= 0)
             {
                 return true;

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java?rev=1296363&r1=1296362&r2=1296363&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java Fri Mar  2 18:28:11 2012
@@ -1357,22 +1357,26 @@ public class UIViewRoot extends UICompon
     private Events _getEvents(PhaseId phaseId)
     {
         // Gather the events and purge the event list to prevent concurrent modification during broadcasting
-        List<FacesEvent> anyPhase = new ArrayList<FacesEvent>(
-                _events.size());
-        List<FacesEvent> onPhase = new ArrayList<FacesEvent>(_events.size());
-        for (Iterator<FacesEvent> iterator = _events.iterator(); iterator
-                .hasNext();)
+        int size = _events.size();
+        List<FacesEvent> anyPhase = new ArrayList<FacesEvent>(size);
+        List<FacesEvent> onPhase = new ArrayList<FacesEvent>(size);
+        
+        for (int i = 0; i < size; i++)
         {
-            FacesEvent event = iterator.next();
+            FacesEvent event = _events.get(i);
             if (event.getPhaseId().equals(PhaseId.ANY_PHASE))
             {
                 anyPhase.add(event);
-                iterator.remove();
+                _events.remove(i);
+                size--;
+                i--;
             }
             else if (event.getPhaseId().equals(phaseId))
             {
                 onPhase.add(event);
-                iterator.remove();
+                _events.remove(i);
+                size--;
+                i--;
             }
         }
         

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/_ComponentChildrenList.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/_ComponentChildrenList.java?rev=1296363&r1=1296362&r2=1296363&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/_ComponentChildrenList.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/_ComponentChildrenList.java Fri Mar  2 18:28:11 2012
@@ -24,12 +24,13 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.RandomAccess;
 
 /**
  * @author Manfred Geiler (latest modification by $Author$)
  * @version $Revision$ $Date$
  */
-class _ComponentChildrenList extends AbstractList<UIComponent> implements Serializable
+class _ComponentChildrenList extends AbstractList<UIComponent> implements Serializable, RandomAccess
 {
     private static final long serialVersionUID = -6775078929331154224L;
     private UIComponent _component;

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/_DeltaList.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/_DeltaList.java?rev=1296363&r1=1296362&r2=1296363&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/_DeltaList.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/_DeltaList.java Fri Mar  2 18:28:11 2012
@@ -23,6 +23,7 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.RandomAccess;
 
 import javax.faces.context.FacesContext;
 
@@ -42,7 +43,7 @@ import javax.faces.context.FacesContext;
  * @author Leonardo Uribe (latest modification by $Author$)
  * @version $Revision$ $Date$
  */
-class _DeltaList<T> implements List<T>, PartialStateHolder
+class _DeltaList<T> implements List<T>, PartialStateHolder, RandomAccess
 {
 
     private List<T> _delegate;

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/component/visit/PartialVisitContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/component/visit/PartialVisitContext.java?rev=1296363&r1=1296362&r2=1296363&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/component/visit/PartialVisitContext.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/component/visit/PartialVisitContext.java Fri Mar  2 18:28:11 2012
@@ -84,9 +84,9 @@ public class PartialVisitContext extends
     _facesContext = facesContext;
 
     // Copy the client ids into a HashSet to allow for quick lookups.
-    Set<String> clientIdSet = (clientIds == null)
-                                ? new HashSet<String>()
-                                : new HashSet<String>(clientIds);
+//    Set<String> clientIdSet = (clientIds == null)
+//            ? new HashSet<String>()
+//                    : new HashSet<String>(clientIds);
 
     // Initialize our various collections
     // We maintain 4 collections:
@@ -122,8 +122,9 @@ public class PartialVisitContext extends
     _clientIds = new CollectionProxy<String>(new HashSet<String>());
 
     // Finally, populate the clientIds collection.  This has the
-    // side effect of populating all of the other collections.       
-    _clientIds.addAll(clientIdSet);
+    // side effect of populating all of the other collections.
+    org.apache.myfaces.shared.util.ArrayUtils.addAll(_clientIds, clientIds);
+    //_clientIds.addAll(clientIdSet);
 
     // Copy and store hints - ensure unmodifiable and non-empty
     EnumSet<VisitHint> hintsEnumSet = ((hints == null) || (hints.isEmpty()))

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java?rev=1296363&r1=1296362&r2=1296363&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java Fri Mar  2 18:28:11 2012
@@ -19,6 +19,7 @@
 package org.apache.myfaces.lifecycle;
 
 import java.io.IOException;
+import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -115,12 +116,17 @@ class RenderResponseExecutor extends Pha
             viewHandler.renderView(facesContext, root);
             
             // log all unhandled FacesMessages, don't swallow them
-            if (!facesContext.getMessageList().isEmpty())
+            // perf: org.apache.myfaces.context.servlet.FacesContextImpl.getMessageList() creates
+            // new Collections.unmodifiableList with every invocation->  call it only once
+            // and messageList is RandomAccess -> use index based loop
+            List<FacesMessage> messageList = facesContext.getMessageList();
+            if (!messageList.isEmpty())
             {
                 StringBuilder builder = new StringBuilder();
                 boolean shouldLog = false;
-                for (FacesMessage message : facesContext.getMessageList())
+                for (int i = 0, size = messageList.size(); i < size; i++)
                 {
+                    FacesMessage message = messageList.get(i);
                     if (!message.isRendered())
                     {
                         builder.append("\n- ");

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlAjaxBehaviorRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlAjaxBehaviorRenderer.java?rev=1296363&r1=1296362&r2=1296363&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlAjaxBehaviorRenderer.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlAjaxBehaviorRenderer.java Fri Mar  2 18:28:11 2012
@@ -248,22 +248,23 @@ public class HtmlAjaxBehaviorRenderer ex
              * see ClientBehaviorContext.html of the spec
              * the param list has to be added in the post back
              */
-            for (ClientBehaviorContext.Parameter param : params)
+            // params are in 99% RamdonAccess instace created in 
+            // HtmlRendererUtils.getClientBehaviorContextParameters(Map<String, String>)
+            if (params instanceof RandomAccess)
             {
-                //TODO we may need a proper type handling in this part
-                //lets leave it for now as it is
-                //quotes etc.. should be transferred directly
-                //and the rest is up to the toString properly implemented
-                //ANS: Both name and value should be quoted
-                paramBuffer.setLength(0);
-                paramBuffer.append(QUOTE);
-                paramBuffer.append(param.getName());
-                paramBuffer.append(QUOTE);
-                paramBuffer.append(COLON);
-                paramBuffer.append(QUOTE);
-                paramBuffer.append(param.getValue().toString());
-                paramBuffer.append(QUOTE);
-                parameterList.add(paramBuffer.toString());
+                List<ClientBehaviorContext.Parameter> list = (List<ClientBehaviorContext.Parameter>) params;
+                for (int i = 0, size = list.size(); i < size; i++)
+                {
+                    ClientBehaviorContext.Parameter param = list.get(i);
+                    append(paramBuffer, parameterList, param);
+                }
+            }
+            else
+            {
+                for (ClientBehaviorContext.Parameter param : params)
+                {
+                    append(paramBuffer, parameterList, param);
+                }
             }
         }
 
@@ -290,6 +291,24 @@ public class HtmlAjaxBehaviorRenderer ex
         return retVal;
     }
 
+    private void append(StringBuilder paramBuffer, List<String> parameterList, ClientBehaviorContext.Parameter param)
+    {
+        //TODO we may need a proper type handling in this part
+        //lets leave it for now as it is
+        //quotes etc.. should be transferred directly
+        //and the rest is up to the toString properly implemented
+        //ANS: Both name and value should be quoted
+        paramBuffer.setLength(0);
+        paramBuffer.append(QUOTE);
+        paramBuffer.append(param.getName());
+        paramBuffer.append(QUOTE);
+        paramBuffer.append(COLON);
+        paramBuffer.append(QUOTE);
+        paramBuffer.append(param.getValue().toString());
+        paramBuffer.append(QUOTE);
+        parameterList.add(paramBuffer.toString());
+    }
+
 
     private StringBuilder buildOptions(FacesContext facesContext, StringBuilder retVal, List<String> options)
     {

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlFormatRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlFormatRenderer.java?rev=1296363&r1=1296362&r2=1296363&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlFormatRenderer.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlFormatRenderer.java Fri Mar  2 18:28:11 2012
@@ -173,8 +173,9 @@ public class HtmlFormatRenderer extends 
             {
                 List<UIParameter> validParams = HtmlRendererUtils.getValidUIParameterChildren(
                         facesContext, htmlOutputFormat.getChildren(), false, false, false);
-                for (UIParameter param : validParams)
+                for (int i = 0, size = validParams.size(); i < size; i++)
                 {
+                    UIParameter param = validParams.get(i);
                     if (argsList == null)
                     {
                         argsList = new ArrayList<Object>();

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java?rev=1296363&r1=1296362&r2=1296363&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java Fri Mar  2 18:28:11 2012
@@ -869,8 +869,11 @@ public class FaceletViewDeclarationLangu
             // note it is also called curTargetName
             String forValue = currentHandler.getFor();
             
-            for (AttachedObjectTarget currentTarget : targetList)
+            // perf: targetList is always arrayList: see AttachedObjectTargetHandler.apply 
+            // and ClientBehaviorHandler.apply 
+            for (int k = 0, targetsSize = targetList.size(); k < targetsSize; k++)
             {
+                AttachedObjectTarget currentTarget = targetList.get(k);
                 FaceletCompositionContext mctx = FaceletCompositionContext.getCurrentInstance();
 
                 if ((forValue != null && forValue.equals(currentTarget.getName())) &&
@@ -881,8 +884,11 @@ public class FaceletViewDeclarationLangu
                                 (currentTarget instanceof ValueHolderAttachedObjectTarget &&
                                         currentHandler instanceof ValueHolderAttachedObjectHandler)))
                 {
-                    for (UIComponent component : currentTarget.getTargets(topLevelComponent))
+                    // perf: getTargets return ArrayList - see getTargets implementations
+                    List<UIComponent> targets = currentTarget.getTargets(topLevelComponent);
+                    for (int l = 0, targetsCount = targets.size(); l < targetsCount; l++)
                     {
+                        UIComponent component = targets.get(l);
                         // If we found composite components when traverse the tree
                         // we have to call this one recursively, because each composite component
                         // should have its own AttachedObjectHandler list, filled earlier when

Modified: myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java?rev=1296363&r1=1296362&r2=1296363&view=diff
==============================================================================
--- myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java (original)
+++ myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java Fri Mar  2 18:28:11 2012
@@ -2164,10 +2164,12 @@ public final class HtmlRendererUtils
         {
             finalParams.add('\'' + escapeJavaScriptForChain(serverEventCode) + '\'');
         }
-        Iterator<String> it = finalParams.iterator();
+        
         // It's possible that there are no behaviors to render.  For example, if we have
         // <f:ajax disabled="true" /> as the only behavior.
-        if (it.hasNext())
+        
+        int size = finalParams.size();
+        if (size > 0)
         {
             if (!submitting)
             {
@@ -2177,10 +2179,12 @@ public final class HtmlRendererUtils
             //behavior and scripts
             retVal.append("jsf.util.chain(document.getElementById('"
                     + targetClientId + "'), event,");
-            while (it.hasNext())
+            int cursor = 0;
+            while (cursor != size)
             {
-                retVal.append(it.next());
-                if (it.hasNext())
+                retVal.append(finalParams.get(cursor));
+                cursor++;
+                if (cursor != size)
                 {
                     retVal.append(", ");
                 }

Modified: myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/util/ArrayUtils.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/util/ArrayUtils.java?rev=1296363&r1=1296362&r2=1296363&view=diff
==============================================================================
--- myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/util/ArrayUtils.java (original)
+++ myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/util/ArrayUtils.java Fri Mar  2 18:28:11 2012
@@ -19,6 +19,9 @@
 package org.apache.myfaces.shared.util;
 
 import java.lang.reflect.Array;
+import java.util.Collection;
+import java.util.List;
+import java.util.RandomAccess;
 
 /**
  * Utility class for managing arrays
@@ -228,7 +231,29 @@ public class ArrayUtils
         return false;
     }
 
-
+    /**
+     * Same as {@link Collection#addAll(Collection)} but in case of RandomAccess iterates over indices 
+     */
+    public static <T> void addAll(Collection<? super T> collection, Collection<? extends T> toAdd)
+    {
+        if (collection == null || toAdd == null)
+        {
+            return;
+        }
+        if (toAdd instanceof RandomAccess)
+        {
+            List<? extends T> randomAccess = (List<? extends T>) toAdd;
+            for (int i = 0, size = randomAccess.size(); i < size; i++)
+            {
+                T element = randomAccess.get(i);
+                collection.add(element);
+            }
+        }
+        else
+        {
+            collection.addAll(toAdd);
+        }
+    }
 
 //    public static void main(String[] args)
 //    {