Community
Participate
Working Groups
Build Identifier: 20110913 nightly build Created 10 RuiHandler with 5000 lines code. The generation elapsed time over 5 min. Which only spend 15sec in RBD. Reproducible: Always Steps to Reproduce: 1. Create new Client Web Project. 2. Create package client.package1 3. Copy RuiHandlers in attachment to package1 4. Project will build automatically and generate JavaScript code. 5. The elapsed time is over 5min.
Created attachment 203201 [details] source code
I spent some time looking into this issue today, and I have created a temporary patch that others may want to try if they are finding performance to be an issue. Profiling this test case reported the following hot spots: 1) Every call to context.putAttribute was resulting in a cache miss when trying to find the type for the annotation to create. In this test case, for just the assignment statements that are generated, there are 4 calls to context.putAttribute with Constants.EXPR_LHS as the annotation type. When there is a cache miss, 3 exceptions are thrown; MOFObjectNotFoundException, which is caught and thrown as a TypeNotFoundException, which is caught and thrown as a RuntimeException. The type resolution code then catches this Runtime Exception, modifies the type name, and attempts the lookup again. In this testcase, 50K assignment statements are generated, which results in 200K cache misses and 600K exceptions being created. To avoid this, I have modified putAttribute to modify the type signature of the annotation before invoking factory.createAnnotation, so that there is no cache miss. I searched for all references to putAttribute, and they all seem to be using some form of Constants.<value>, so hopefully it is safe to modify the type name before createAnnotation is invoked. While I think this solution works for now, I think we will need to find something better. 2) After fixing the issue above, the next hot spot became AbstractVisitor.primGetMethod, which is used to resolve template methods during generation. To solve this issue, I created a static multi-tier hash map to store the resolved methods. The maps are: Methods for the Current Class Current Class -> Map of Methods by Parameter Type: This map is used to hold the resolved methods for 'this.getClass()'. Map of Methods by Parameter Type Parameter Type -> Map of Methods by Name: This map is used to hold all of the methods in 'this.getClass()' that have a single parameter of type 'clazz'. Map of Methods by Name Name -> Method: This map is initialized to be of size 2 and holds the "visit" and "endVisit" methods that match the single parameter type 'clazz' for 'this.getClass'. When resolving a method, if none is found for the current class, we store an object named UNRESOLVED_METHOD in the 'Map of Methods by Name' so that we do not need to iterate over the methods of 'this.getClass()' again. NOTE: Since the Methods for the Current Class map is static, the workspace will need to be restarted, or the map will need to be cleared manually, if template code is hot swapped. Also, we may need to consider capping the size of this cache if it gets too large. 3) The next hot spot appears to be AbstractEnvironment.lookup, where the issue involves looking on the file system to see if a part exists. The testcase attached to this defect takes a total of 265K MS to do a clean build after the changes above have been applied. 59K MS of that time is spent in AbstractEnvironment.lookup.
Created attachment 203311 [details] CVS Patch This patch is experimental. It should not be placed in CVS at this time.
Brian, Thanks alot for investigating; as you know, I tried your patch with my EDT wks and it seems promising....
Brian, any plan to make this fix formal. I think the fix for AbstractVisitor.primGetMethod will help in all places that uses the IR visitor. For example, In VE, most work is around regen the JS and HTML, and both uses IR visit a lot. I tried the patch with my workspace, and there's visible performance improvement in VE even for a simple Handler.
The following change was checked in on October 13, 2011: IRFactory IRFactoryImpl Egl2MofBase - When creating an EGL Location annotation, we are now invoking IRFactory.createDynamicAnnotation instead of trying to create a standard annotation and then falling back on a Dynamic annotation.
We are currently investigating a change to AbstractVisitor that caches 'visit' and 'endVisit' template methods. In addition to caching methods that are found, this update will also cache which methods are NOT found, so that we can avoid unnecessary method searches in the future. While this change does improve performance significantly, we are investigating the memory usage for 'method misses' and devising a solution that improves performance and does not use a lot of memory.
AbstractVisitor.java has been updated with a large performance improvement by caching hits and misses. I'm leaving this open in case there are still other areas to look at.
No more problems have been reported in the past year, so I'm resolving this bug.