You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by "Leonardo Uribe (JIRA)" <de...@myfaces.apache.org> on 2011/07/22 23:00:58 UTC

[jira] [Created] (MYFACES-3236) UIData performance improvements

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.1.1, 2.0.7
            Reporter: Leonardo Uribe
            Assignee: Leonardo Uribe


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

        

[jira] [Resolved] (MYFACES-3236) UIData performance improvements

Posted by "Leonardo Uribe (JIRA)" <de...@myfaces.apache.org>.
     [ 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