[
https://issues.apache.org/jira/browse/MYFACES-2156?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12714129#action_12714129
]
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);
}
else
{
//Log override
}
familyRendererMap.put(rendererType, renderer);
}
The reason to do that here is prevent create a familyRendererMap twice and lost
one renderer configuration.
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.
regards
Leonardo
> Performance improvement in HtmlRenderKitImpl
> --------------------------------------------
>
> Key: MYFACES-2156
> URL: https://issues.apache.org/jira/browse/MYFACES-2156
> 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.