Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance deviation for a small method

We have an OSGi container with a lot of products running inside, one of them being our product.
We have some performance tests running and there is this weird problem that, every OSGi container restart will result in a performance deviation for some of our tests up to 400%.
Through some testing and things I was able to track this down to this method:

public static Method getMethodForSlotKey(Class<?> cls, String slotKey, String methodType) {

    Method[] methods = cls.getMethods();

    if (methods != null && methods.length > 0) {
        for (Method method : methods) {
            String methName = method.getName();
            if (methName.startsWith(methodType)) {

                IDataAnnotation annot = method.getAnnotation(IDataAnnotation.class);
                if (annot != null) {
                    String annotSlotKey = annot.SlotKey();
                    if (annotSlotKey != null && annotSlotKey.equals(slotKey)) {
                        Class<?>[] paramTypes = method.getParameterTypes();
                        // for now, check length == 1 for setter and 0 for getter.
                        int len = SET_TXT.equals(methodType) ? 1 : 0;
                        if (paramTypes != null && paramTypes.length == len) {
                            return method;
                        }
                    }
                }
            }
        }
    }
    return null;
}

This method mainly does reflection and string comparison.

Now, what I did is to cache the results of this method and instantly our deviation goes down to 10 - 20%. Of course, this method is called often, so that there is am improvement is obvious.

Still I don't understand why the non-cached version has such a high deviation with the only difference being a OSGi / JVM restart? What exactly may happen during the restart? Are there any known performance issues for different classloaders for instance? Is it possible that in the OSGi environment libraries will be loaded in a different order between the restarts?

I am searching for a clue here for this to make sense.

UPDATE

It turns out that this call:

Method[] methods = cls.getMethods();

is causing the deviation. I still don't understand it, so if anyone does I'd be happy to hear about it.

like image 613
sveri Avatar asked Jan 13 '15 16:01

sveri


People also ask

What is considered a small standard deviation?

As a rule of thumb, a CV >= 1 indicates a relatively high variation, while a CV < 1 can be considered low. This means that distributions with a coefficient of variation higher than 1 are considered to be high variance whereas those with a CV lower than 1 are considered to be low-variance.

Is it better for standard deviation to be large or small?

A high standard deviation shows that the data is widely spread (less reliable) and a low standard deviation shows that the data are clustered closely around the mean (more reliable).

What is deviation in performance?

A low deviation value indicates that the data points tend to be very close to the mean, whereas a high deviation value indicates that the data are spread out over a large range of values. A low standard deviation implies that there is a more stable, or consistent, performance within the system.


1 Answers

It seems like this is another case of the intricate JIT, which seems to constantly change and evolve with time. This answer may shed some light on your issue: Java: what is JITC's reflection inflation?

I believe you are observing the aftereffects of how JIT optimizes your reflection calls. For a while (the first X invocations) would be slow until JIT decides to optimize your method.

Something you can try - to test this theory - is to modify your code and put the offending call in a dummy loop and execute it a number of times on the very first call (make sure you do something with the result from the call to force java to not optimize away the call completely, if it figures it has no consequences). If this results in a very long execution time for the first use and then very low variance on the subsequent calls, then the theory sounds correct.

like image 126
xpa1492 Avatar answered Nov 15 '22 13:11

xpa1492