[ https://issues.apache.org/jira/browse/MYFACES-3236?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Leonardo Uribe resolved MYFACES-3236. ------------------------------------- Resolution: Fixed Fix Version/s: 2.1.2 2.0.8 > UIData performance improvements > ------------------------------- > > Key: MYFACES-3236 > URL: https://issues.apache.org/jira/browse/MYFACES-3236 > Project: MyFaces Core > Issue Type: Improvement > Components: JSR-314 > Affects Versions: 2.0.7, 2.1.1 > Reporter: Leonardo Uribe > Assignee: Leonardo Uribe > Fix For: 2.0.8, 2.1.2 > > > Some days ago there was a discussion on dev list titled: > [core] performance: performance hints > With the following intention (proposed by Martin Koci): > MK>> is it possible to introduce performance hints in myfaces-core? Hints > MK>> similar to javax.faces.component.visit.VisitHint but related to > MK>> performance improvements. Example: > > MK>> For dataTable like: > MK>> <a:dataTable > MK>> <a:column> > MK>> #{aExpression} > > MK>> it's completely unnecessary to save per-row state. Currently there > is no > MK>> elegant way how to do read-only table (state per-row is always > MK>> maintained). If user wants (fast) readOnly table, he/she must extend > MK>> UIData and re-implemenent setRowIndex method. But hint say > MK>> "org.apache.myfaces.core.UIData.saveRowState"=false can solve it > MK>> elegantly - if present (in component.getAttributes()) UIData skips > MK>> row-state-saving and restoring methods entirely. > > MK>> Lifespan of those hints can be request (faceContext.attributes) or > view > MK>> (component.attributes) > > The discussion there was to create or not a hint but a review of the default > algorithm was never done. In theory, UIData.setRowIndex do the following > tasks: > 1. If the component is in row -1 (no row), take a "snapshot" of the > components that implements EditableValueHolder, to restore them later when > rows are traversed. > 2. If the component is in a row, save the current state of > EditableValueHolder components. > 3. Move to the selected row. > 4. If no state saved found, restore EditableValueHolder components from saved > initial state. > 5. If state saved found, restore EditableValueHolder components from stored > saved state. > After an in-deep analysis, the conclusion was it is not really necessary to > create the hint. Instead, we can create a better algorithm that take > advantage of > the fact that add a non transient EditableValueHolder component inside a > dataTable row on render response time leads to a illegal state. > Since UIData.setRowIndex is a code that is called multiple times, specially > for large datatable sets. Doing some performance tests, it was notice the > current > algorithm uses a lot of memory resources. The proposal is do the following: > 1. Iterate using index instead iterator for children. This can duplicate the > lines of code > 2. Do not create Object[]{null,null} instances, use a private static final > variable. > 3. Cache DataListener[]. > 4. If no EditableValueHolder instances found, skip state saving code, but > reset all ids. > 5. Prevent unnecessary calls to getContainerClientId(). > 6. Provide initial size for created ArrayList instances to reduce memory > usage. > 7. Iterate over row state using index, instead iterator, and take advantage > instances are ArrayList. > 8. Do not instantiate ArrayList, unless it is necessary. > > Tests done shows a really big improvement, specially when non > EditableValueHolder component instances are inside the datatable, which is a > very common use case. > Based on this patch we can do other things like: > 1. Port this code to UIRepeat. > 2. Port this code to Tomahawk. > 3. Reuse already created state instances, which can improve performance on > postback requests. -- This message is automatically generated by JIRA. For more information on JIRA, see: http://www.atlassian.com/software/jira