Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaParser.addExpectedElement() - JavaContainmentTrace instantiation #14

Open
BenjaminKlatt opened this issue Jan 1, 2014 · 0 comments

Comments

@BenjaminKlatt
Copy link
Contributor

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.

jamopp-method-hotspots-original

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

org.emftext.language.java.resource.java.mopp.JavaExpectationConstants.EXPECTATIONS[]

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 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)

MLanghammer pushed a commit to MLanghammer/JaMoPP that referenced this issue Dec 22, 2015
MLanghammer pushed a commit to MLanghammer/JaMoPP that referenced this issue Dec 22, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant