dev@javaserverfaces.java.net

Re: Pass-through attribute rendering - how do we optimize this?

From: Ryan Lubke <Ryan.Lubke_at_Sun.COM>
Date: Sat, 01 Sep 2007 18:27:37 -0700

I think I have a solution to this problem (improves on solution 2, but
doesn't add the complexity from
solution 3).

I'll prototype over the weekend and post a change bundle early next week.

Ryan Lubke wrote:
> PROBLEM:
>
> In our current implementation, each renderer has an array of known
> passthrough
> attributes it needs to handle. When the component is rendered,
> this array is passed
> to RenderKitUtils.renderPassThruAttributes(). The logic here is
> pretty simple, we
> iterate through all of the known attributes and call
> component.getAttributes(). If we
> have a non-null return, we render the attribute.
>
> So as a simple example using the UIData.jsp example in the
> jsf-standard demo,
> we spend about 1872 ms over 1461 invocations. Most of this time is
> spent (1148ms)
> calling Method instances since most, if not all, of the
> pass-through attributes on the
> Html components map to java properties.
> I think in general it would be safe to say that it's not the norm
> for a component to have
> more than 6 pass-through attributes defined, so if a component has
> a total of 20 pass through
> attributes, then we waste a lot of cycles when only 6 or so need to
> be rendered.
>
> --------------------------------------------------------------------------
>
> SOLUTION 1:
> - Add a package-private List<String> to UIComponent with a method
> to will create/return the
> list. This list would be stored within the UIComponent
> instance's attribute map.
> - Update the implementation for UIComponent.setValueExpression()
> and the attribute map
> implementation to add attribute names to this list.
> - When rendering, check for the existence of this List. If
> present, then call an optimized
> version of RenderKitUtils.renderPassThroughAttributes() which
> will, for each of the
> attribute names in the List, search the known pass-through
> attributes for this component
> and render them.
>
> PROBLEMS WITH SOLUTION 1:
> - what if a developer uses a component binding where they create
> the component,
> call a setter (which maps to a pass-through attribute) against
> the component directly,
> and then call getAttributes().put(), or set a value expression?
> This would cause the
> list to be created which would trigger the optimized rendering
> path, but the value set
> via setter wouldn't be known, and thus wouldn't be rendered.
> --------------------------------------------------------------------------
>
>
> --------------------------------------------------------------------------
>
> SOLUTION 2:
> - Add a package-private List<String> to UIComponent with a
> method to will create/return the
> list. This list would be stored within the UIComponent
> instance's attribute map.
> - Update the implementation for
> UIComponent.setValueExpression() and the attribute map
> implementation to add attribute names to this list.
> - Update the HTML component generator to:
> - for each setter that maps to a pass-through attribute, ensure
> it will add the attribute name to the list.
> - for each pass-through attribute of the component that has a
> default property (such a HtmlForm's enctype),
> ensure the attribute is added to the list when the component
> is instantiated.
>
> PROBLEMS WITH SOLUTION 2:
> - The main problem with solution 1 is solved, but now, what if a
> developer extends
> the default HTML component and overrides a method mapping to a
> pass-through
> attribute and never calls super()? Some other causes the
> attribute list to be created,
> but because how the developer overrode the method, that
> attribute isn't in the list and
> therefore doesn't get rendered.
> --------------------------------------------------------------------------
>
>
> --------------------------------------------------------------------------
>
> SOLUTION 3:
> - Based on solution 2, but add a static marker to the generated
> component denoting
> it's suitable to be optimized.
> - Update ApplicationImpl.createComponent() to check for this
> marker and if present,
> add a flag (probably to the attributes map) that can be picked
> up by the rendering
> logic to select the appropriate rendering method. This would
> solve the issue
> with solution 2.
>
> PROBLEMS WITH SOLUTION 3:
> - Adding some overhead to the ApplicationImpl.createComponent()
> code path (probably minor)
> - An application developer completely replaces the Application
> object or overrides createComponent()
> so that nothing gets flagged, so rendering occurs as it does
> now (back to square one).
> --------------------------------------------------------------------------
>
>
> Issues aside, I've implemented solution 2 locally, and have seen a
> very nice improvment in
> the rendering. Specifically, for a similar number of invocations, the
> time rendering pass through
> attributes was reduced to 384 ms.
>
> So, I'm looking for feedback:
> - thoughts on each solution
> - solutions that haven't been considered
> - other problems that haven't been considered
> - Is the performance gain mentioned worth the additional complexity?
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_javaserverfaces.dev.java.net
> For additional commands, e-mail: dev-help_at_javaserverfaces.dev.java.net
>