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.
Within java model classes, standard library classes such as java.lang.Object are accessed through CommentableImpl.getLibClass(String)
There are already some convienience methods provided by CommentableImpl such as getObjectClass()
However, even those methods call the getLibClass(String) methods for every call by themselves.
Profiling a parse process for a short time already shows a lot of requests send to getLibClass even through getObjectClass().
Extensive Processing
There are two important issues for that:
1) Repetitive Calls
Methods such as getObjectClass() call getLibClass(String) with the same string parameter every time. So the result is always the same
public org.emftext.language.java.classifiers.Class getObjectClass() {
return getLibClass("Object");
}
2) Complex Processing in getLibClass(String)
getLibClass(String) internally uses a complex processing for every request including String concatenation, EcoreUtil resolving, instanceof checks, etc.
Improvements
There are two major and one minor recommendations to improve this:
1. Use Caching
Change convenience methods such as getObjectClass() to cache the result and do not forward each request to getLibClass().
Example:
Note:
Important things to consider for this caching
A static cache won't work for two or more parsings running in the same JVM.
Preloading the cache during class initialization might fail du to missing runtime library availability at class initialization.
2. Additional Convenience Methods with Caching
Introduce additional convenience methods for other standard library classes accessed statically within the meta model implementation.
In addition to java.lang.Object or java.lang.String, other java.lang classes such as java.lang.Integer are accessed in a repetitive manner. For those accesses, similar cache enabled convinience methods can be introduced and the pimitive getLibClass() calls can be replaced.
Improvement Evaluation
To check the number of getLibClass() invocations, parallel parsings of the two variants of the Calculator Example available at http://sdqweb.ipd.kit.edu/wiki/Calculator_Example was performed. Even with this small example, the number of getLibClass() invocation could be significantly reduced using the recommendations described above:
Code Version
#invocations of getLibClass()
original implementation
2483
caches for getObjectClass() & getClassClass()
999
cache getStringClass()
943
cache getBooleanClass()
885
cache getVoidClass()
625
cache getEnumClass()
624
cache getByteClass() & getCharacterClass()
513
cache float, double, integer
372
cache long, short
299
make getIntegerClass() available in Commentable interface and use this in FieldDecider
294
Only the last modification required to change the Commentable interface. All other improvements have been done in the implementation only.
Obeserved High Amount of Method Calls
Within java model classes, standard library classes such as java.lang.Object are accessed through CommentableImpl.getLibClass(String)
There are already some convienience methods provided by CommentableImpl such as getObjectClass() However, even those methods call the getLibClass(String) methods for every call by themselves.
Profiling a parse process for a short time already shows a lot of requests send to getLibClass even through getObjectClass().
Extensive Processing
There are two important issues for that:
1) Repetitive Calls
Methods such as getObjectClass() call getLibClass(String) with the same string parameter every time. So the result is always the same
2) Complex Processing in getLibClass(String)
getLibClass(String) internally uses a complex processing for every request including String concatenation, EcoreUtil resolving, instanceof checks, etc.
Improvements
There are two major and one minor recommendations to improve this:
1. Use Caching
Change convenience methods such as getObjectClass() to cache the result and do not forward each request to getLibClass(). Example:
Note: Important things to consider for this caching
2. Additional Convenience Methods with Caching
Introduce additional convenience methods for other standard library classes accessed statically within the meta model implementation. In addition to java.lang.Object or java.lang.String, other java.lang classes such as java.lang.Integer are accessed in a repetitive manner. For those accesses, similar cache enabled convinience methods can be introduced and the pimitive getLibClass() calls can be replaced.
Improvement Evaluation
To check the number of getLibClass() invocations, parallel parsings of the two variants of the Calculator Example available at http://sdqweb.ipd.kit.edu/wiki/Calculator_Example was performed. Even with this small example, the number of getLibClass() invocation could be significantly reduced using the recommendations described above:
Only the last modification required to change the Commentable interface. All other improvements have been done in the implementation only.