April 15, 2006

Performance of Spring CGLIB and JDK proxies

So I noticed a couple of questions popping up on the Spring forums asking about the cost of using AOP in Spring. This is really a question of how expensive CGLIB or JDK proxies are.

Since I had no real idea (there are lots of "not than expensive" comments around) I decided to write a little test.

Essentially I construct X instances of a class, X instances of a CGLIB proxy of that class (cglib sub classes the target class) and X instances of a JDK proxy, and then called the same method on each instance and measured the time. Hardly conclusive, but enough to give an idea.

I assumed the impact was minimal; when X is 10000:

Unproxied: 926654(ns) 9(ms)
cglib: 23986289(ns) 239(ms)
Proxy: 70206129(ns) 702(ms)

I expected some over head, but notwhere near that much….. I was also suprised that CGLIB was almost 3 times quicker than JDK proxies (JDK1.5.0_06 on WinXP SP2).

It is still a long way away from being the bottleneck in any system I am likely to write, but good to know :)

I expect AspectJ style weaving is probably a lot more efficient because (IIUI) it modified the byte code directly. Of course, there is an overhead of the modification, but that is a one off…. But I may be so completely wrong :)

Code:


public class MyClassImpl implements MyClass {
    public void doSomething() {
        
    }
}

public interface MyClass {
    void doSomething();
}

import junit.framework.TestCase;

import org.springframework.aop.framework.ProxyFactoryBean;

public final class ProxyTest extends TestCase {
    public void testPerformance() {
        int numberToExecute = 10000;
        MyClass[] classes = new MyClass[numberToExecute];
        for (int i = 0; i< numberToExecute; i++) {
            classes[i] = new MyClassImpl();
        }
        
        MyClass[] cglibProxyClasses = new MyClassImpl[numberToExecute];
        for (int i = 0; i< numberToExecute; i++) {
            ProxyFactoryBean factoryBean = new ProxyFactoryBean();
            factoryBean.setProxyTargetClass(true);
            factoryBean.setTarget(classes[i]);
            cglibProxyClasses[i] = (MyClass) factoryBean.getObject();
        }
        
        MyClass[] proxyClasses = new MyClass[numberToExecute];
        for (int i = 0; i< numberToExecute; i++) {
            ProxyFactoryBean factoryBean = new ProxyFactoryBean();
            factoryBean.setProxyTargetClass(false);
            factoryBean.setInterfaces(new Class[] {MyClass.class });
            factoryBean.setTarget(classes[i]);
            proxyClasses[i] = (MyClass) factoryBean.getObject();
        }
        
        long unproxyExecution = executeClasses(numberToExecute, classes);
        displayResults("Unproxied", unproxyExecution);
        
        long cglibExecution = executeClasses(numberToExecute, cglibProxyClasses);
        displayResults("cglib", cglibExecution);

        long proxyExecution = executeClasses(numberToExecute, proxyClasses);
        displayResults("Proxy", proxyExecution);
    }

    private void displayResults(String label, long unproxyExecution) {
        System.out.println(label + ": " + unproxyExecution + "(ns) " + (unproxyExecution / 100000) + "(ms)");
    }

    private long executeClasses(int numberToExecute, MyClass[] classes) {
        long start = System.nanoTime();
        for (int i = 0; i< numberToExecute; i++) {
            classes[i].doSomething();
        }
        long end = System.nanoTime();
        long execution = end – start;
        return execution;
    }
}

- One comment Not publicly viewable

  1. Alexander Snaps

    Interesting… While I’m not completely convinced in such microbenchmarks, I’m pretty sure that 1ms = 1,000,000 ns and not 100,000 ;)
    Sort of reassuring, cause thought your figures were pretty low…

    29 Nov 2007, 05:24


Add a comment

You are not allowed to comment on this entry as it has restricted commenting permissions.

Trackbacks

April 2006

Mo Tu We Th Fr Sa Su
Mar |  Today  | May
               1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Search this blog

Tags

Galleries

Most recent comments

  • Interesting… While I’m not completely convinced in suc… by Alexander Snaps on this entry
  • Hello. I bought the book yesterday. I was trying to find the source… by Suleman on this entry
  • http://woosight.net/account/login?username=demo by live mashup demo on this entry
  • Thanks mate ….. This blog was really helpful. by Maaz Hurzuk on this entry
  • Ty. Not directly helpful for my problem, but pointed me in the righ… by Mike E. on this entry

Blog archive

Loading…
Not signed in
Sign in

Powered by BlogBuilder
© MMXIII