DevBoost / JaMoPP

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.
17 stars 18 forks source link

Java Library class access Improvements #22

Closed BenjaminKlatt closed 10 years ago

BenjaminKlatt commented 10 years ago

Obeserved High Amount of Method Calls

Within java model classes, standard library classes such as java.lang.Object are accessed through CommentableImpl.getLibClass(String) getlibclass_search

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(). getstdclasses

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:

    public org.emftext.language.java.classifiers.Class getObjectClass() {
        if(objectClass == null) {
            objectClass = getLibClass("Object"); 
        }
        return objectClass;
    }
    private org.emftext.language.java.classifiers.Class objectClass = null;

Note: Important things to consider for this 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.