JaMoPP can parse Java source and byte code into EMF-based models and vice versa. It preserves source formatting and can be used for code analysis and refactoring.
Inside the JavaParser, the addExpectedElement method is called quite often (>20.000 times). With a case study based on an ArgoUML example performed in context of the SPLevo / KoPL project, this method is called more the 141.5 billion times.
There seems to be no (obvious) way to reduce the number of invocation due to the parser logic because some parser status dependend processing is done in it. But there is also some data created that is neither status dependend nor modified later.
With each method invocation, an instance of JavaContainmentTrace is created which is an opportunity the caching.
Information Gathered from Code Review
In the original state of the code, the addExpectedElement method receives an eClass and an array of integers.
First: Investigating more in how the method is called, this array is always derieved from a static array
Changing the method signature, to receive the index of the Expectations array and solve the reference inside of addExpectedElement() allows for a better cache design.
Second: Investigating further in the dependence between the Expectations array and the provided eClass, there is a 1:1 relationship between those two. The EClass can be derived from the logic implemented for the static data build up inside addExpectedElement(), more specific from the data provided by JavaContainedFeature / JavaFollowSetProvider.
This constellation further allows for easier cache design and to remove the eClass attribute of the addExpectedElement() method.
Adapt Method Calls
Based on Eclipse's regular-expression-based search and replace perform the following replace all invocations:
Change method signature to public void addExpectedElement(int expectationId).
Add statement int[] ids = JavaExpectationConstants.EXPECTATIONS[expectationId]; after the if() configuration check
ContainmentTraceCache
A cache to statically initialize all containmentTrace objects needed during processing.
Based on the observations described above, the pre-initialized JavaContainmentTrace instances can be cached and received based on the expectationId only. This is done with a statically initialized LinkedHashMap. As an alternative, Google Guava Caching could be used but would require an additional dependency for JaMoPP.
As a result, only as much instances of JavaContainmentTrace objects are required as the EXPECTATIONS specification array has entries (~21k) and not as often the as JavaParser.addExpectedElement() is invoked during runtime (>141 billion in the case study)
Background
Inside the JavaParser, the addExpectedElement method is called quite often (>20.000 times). With a case study based on an ArgoUML example performed in context of the SPLevo / KoPL project, this method is called more the 141.5 billion times.
There seems to be no (obvious) way to reduce the number of invocation due to the parser logic because some parser status dependend processing is done in it. But there is also some data created that is neither status dependend nor modified later. With each method invocation, an instance of JavaContainmentTrace is created which is an opportunity the caching.
Information Gathered from Code Review
In the original state of the code, the addExpectedElement method receives an eClass and an array of integers.
First: Investigating more in how the method is called, this array is always derieved from a static array
Changing the method signature, to receive the index of the Expectations array and solve the reference inside of
addExpectedElement()
allows for a better cache design.Second: Investigating further in the dependence between the Expectations array and the provided eClass, there is a 1:1 relationship between those two. The EClass can be derived from the logic implemented for the static data build up inside addExpectedElement(), more specific from the data provided by JavaContainedFeature / JavaFollowSetProvider. This constellation further allows for easier cache design and to remove the eClass attribute of the addExpectedElement() method.
Adapt Method Calls
Based on Eclipse's regular-expression-based search and replace perform the following replace all invocations:
Search for:
org.emftext.language.java.resource.java.mopp.JavaExpectationConstants.EXPECTATIONS\[([0-9]*)\]\);
Replace with:$1\);
Search for:
addExpectedElement\(([a-zA-Z\.\_]*\(\)\,) ([0-9]*)\);
Replace with:addExpectedElement($2);
Search for:
addExpectedElement\(null, ([0-9]*)\);
Replace with:addExpectedElement($1);
Change method signature to
public void addExpectedElement(int expectationId)
. Add statement int[] ids = JavaExpectationConstants.EXPECTATIONS[expectationId]; after theif()
configuration checkContainmentTraceCache
A cache to statically initialize all containmentTrace objects needed during processing. Based on the observations described above, the pre-initialized JavaContainmentTrace instances can be cached and received based on the expectationId only. This is done with a statically initialized LinkedHashMap. As an alternative, Google Guava Caching could be used but would require an additional dependency for JaMoPP.
As a result, only as much instances of JavaContainmentTrace objects are required as the EXPECTATIONS specification array has entries (~21k) and not as often the as JavaParser.addExpectedElement() is invoked during runtime (>141 billion in the case study)