dev@javaserverfaces.java.net

[REVIEW] Performance enhancement to HtmlBasicRenderer.getChildren()

From: Ryan Lubke <Ryan.Lubke_at_Sun.COM>
Date: Wed, 21 Jun 2006 12:37:37 -0700


For JSF_1_1_ROLLING.
HtmlBasicRenderer.getChildren() shows up as a major
CPU bottleneck. Wrapping the component's children
iterator with an iterator that only returns
renderable children seems to have eliminated
the issue.


SECTION: Modified Files
----------------------------
M src/com/sun/faces/renderkit/html_basic/HtmlBasicRenderer.java


SECTION: Diffs
----------------------------
Index: src/com/sun/faces/renderkit/html_basic/HtmlBasicRenderer.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/html_basic/HtmlBasicRenderer.java,v
retrieving revision 1.85.26.1.2.2
diff -u -r1.85.26.1.2.2 HtmlBasicRenderer.java
--- src/com/sun/faces/renderkit/html_basic/HtmlBasicRenderer.java 12 Apr 2006 18:33:20 -0000 1.85.26.1.2.2
+++ src/com/sun/faces/renderkit/html_basic/HtmlBasicRenderer.java 21 Jun 2006 19:36:20 -0000
@@ -483,16 +483,12 @@
      */
     protected Iterator getChildren(UIComponent component) {
 
- List results = new ArrayList();
- Iterator kids = component.getChildren().iterator();
- while (kids.hasNext()) {
- UIComponent kid = (UIComponent) kids.next();
- if (kid.isRendered()) {
- results.add(kid);
- }
+ int childCount = component.getChildCount();
+ if (childCount > 0) {
+ return new RenderedChildIterator(component.getChildren().iterator());
+ } else {
+ return Collections.EMPTY_LIST.iterator();
         }
- return (results.iterator());
-
     }
 
 
@@ -589,6 +585,73 @@
 
         public String getValue() {
             return value;
+ }
+ }
+
+ /**
+ * <p>This <code>Iterator</code> is used to Iterator over
+ * children components that are set to be rendered.</p>
+ */
+ private static class RenderedChildIterator implements Iterator {
+
+ Iterator childIterator;
+ boolean hasNext;
+ Object child;
+
+ // -------------------------------------------------------- Constructors
+
+
+ private RenderedChildIterator(Iterator childIterator) {
+
+ this.childIterator = childIterator;
+ update();
+
+ }
+
+
+ // ----------------------------------------------- Methods from Iterator
+
+
+ public void remove() {
+
+ throw new UnsupportedOperationException();
+
+ }
+
+ public boolean hasNext() {
+
+ return hasNext;
+
+ }
+
+ public Object next() {
+
+ Object temp = child;
+ update();
+ return temp;
+
+ }
+
+ // ----------------------------------------------------- Private Methods
+
+ /**
+ * <p>Moves the internal pointer to the next renderable
+ * component skipping any that are not to be rendered.</p>
+ */
+ private void update() {
+
+ while (childIterator.hasNext()) {
+ UIComponent comp = (UIComponent) childIterator.next();
+ if (comp.isRendered()) {
+ child = comp;
+ hasNext = true;
+ return;
+ }
+ }
+
+ hasNext = false;
+ child = null;
+
         }
     }