myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Leonardo Uribe (JIRA)" <>
Subject [jira] Commented: (MYFACES-2156) Performance improvement in HtmlRenderKitImpl
Date Thu, 28 May 2009 19:43:45 GMT


Leonardo Uribe commented on MYFACES-2156:

Hi Martin

Originally the default structure that holds renderers was a simple HashMap.

Right now, one point that need concurrency management is when you add a renderer to the structure:

    synchronized private void _put(String componentFamily, String rendererType, Renderer renderer)
        Map <String,Renderer> familyRendererMap = _renderers.get(componentFamily);
        if (familyRendererMap == null)
            familyRendererMap = (Map<String,Renderer>) new Flat3Map();
            _renderers.put(componentFamily, familyRendererMap);
           //Log override
        familyRendererMap.put(rendererType, renderer);

The reason to do that here is prevent create a familyRendererMap twice and lost one renderer

The default RenderKit is loaded (or addRenderer is called) in two situations:

- On application init.
- On update conditions occur (change on some faces-config related file on /WEB-INF/ path).
Note that when update occur the current RenderKit instance is not reused, a new one is created.

In any case, all renderers are loaded once by a single thread.

 Now, in comparison with trinidad RenderKitBase, the reason why trinidad counterpart uses
a ConcurrentHashMap<String,ConcurrentHashMap<String, Object>> is because trinidad
load renderers on demand (concurrent read and write occur). RenderKitImpl has never experienced
concurrent read and write because by design load all renderers at once and never during the
app lifecycle is added or overridden. 

 The scenario that requires an inner concurrent HashMap is when there are multiple read a
write, but since all write calls are synchronized, and Renderer instances does not have any
inner state, everything is ok.

At this point we have several options:

 1. Keep using a simple Flat3Map
 2. Use a ConcurrentHashMap<String, Object>(8, 0.75f, 1) like RenderKitBase
 3. Wrap Flat3Map with a Collections.synchronizedMap(Map)

 The evidence at this time suggest option 1 is enough, but if some user by some reason add
or override renderers on different moments than current ones use option 2 or 3 is preferred.
Anyway, I think use a ConcurrentHashMap like RenderKitBase could prevent concurrency problems
in any hypothetical case case.



> Performance improvement in HtmlRenderKitImpl
> --------------------------------------------
>                 Key: MYFACES-2156
>                 URL:
>             Project: MyFaces Core
>          Issue Type: Improvement
>    Affects Versions: 1.1.6
>            Reporter: Philipp Schoepf
>            Assignee: Leonardo Uribe
>            Priority: Minor
>             Fix For: 1.2.7-SNAPSHOT
>         Attachments: MYFACES-2156.patch
> we did some profiling in our project and found out that HtmlRenderKitImpl creates some
amount of transient object garbage when getRenderer is called:
> Self   8005   0,00   7,92           0     2894448   
> J:org/apache/myfaces/renderkit/html/HtmlRenderKitImpl.getRenderer(Ljava/lang/String;Ljava/lang/String;)Ljavax/faces/render/Renderer;
>    Child  24015   0,00   4,69           0     1714064   
> J:java/lang/StringBuffer.append(Ljava/lang/String;)Ljava/lang/StringBuffer;
> The above values were recorded with just 2 request to a page with many components - 2.8MB
of transient objects were created by 8005 calls to getRenderer.
> I assume that this is due to the "keying" currenlty implemented which always creates
a concatinated string. I guess using a Map<String, Map<String, Renderer>> doubleMap
could improve the performance here since string creation for keying would not be nessary.
> Might also touch 1.2 and 2.0.

This message is automatically generated by JIRA.
You can reply to this email to add a comment to the issue online.

View raw message