All entries for Saturday 15 April 2006

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 :)


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();
            cglibProxyClasses[i] = (MyClass) factoryBean.getObject();
        MyClass[] proxyClasses = new MyClass[numberToExecute];
        for (int i = 0; i< numberToExecute; i++) {
            ProxyFactoryBean factoryBean = new ProxyFactoryBean();
            factoryBean.setInterfaces(new Class[] {MyClass.class });
            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++) {
        long end = System.nanoTime();
        long execution = end – start;
        return execution;

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



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
  • 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

Not signed in
Sign in

Powered by BlogBuilder