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.

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 such microbenchmarks, I'm pretty sure that 1ms … by Alexander Snaps on this entry
  • Hello. I bought the book yesterday. I was trying to find the source code for chapter 11 and chapter … 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 right direction. You will also get th… by Mike E. on this entry

Blog archive

Loading…
Not signed in
Sign in

Powered by BlogBuilder
© MMXXIII