关于JDK动态代理和CGLib动态代理的性能比较测试。

前言:

动态代理类实现代码参考博客:作者:街灯下的小草

两种动态代理类实现代码:

1、被代理类的接口与实现:

被代理类接口:

/**
 * 被代理类接口
 */
public interface Duck {
    void run(String msg);
}

被代理类:

public class RedHeadDuck implements Duck {
    @Override
    public void run(String msg) {
        System.out.println("run speed:" + msg);
    }
}

JDK动态代理:

public class JDKProxy implements InvocationHandler{
    /** 需要代理的目标对象 */
    private Object targetObject;

    /**
     * 将目标对象传入进行代理
     */
    public Object newProxy(Object targetObject) {
        this.targetObject = targetObject;
        //返回代理对象
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
                targetObject.getClass().getInterfaces(), this);
    }

    /**
     * invoke方法
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        if("run".equals(method.getName())){
            //System.out.println("param is " + args);
        }
        // 设置方法的返回值
        Object ret = null;
        // 调用invoke方法,ret存储该方法的返回值
        ret  = method.invoke(targetObject, args);
        return ret;
    }

}

CGLib动态代理:

public class CGLibProxy implements MethodInterceptor{
    /** CGLib需要代理的目标对象 */
    private Object targetObject;

    public Object createProxyObject(Object obj) {
        this.targetObject = obj;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(obj.getClass());
        enhancer.setCallback(this);
        Object proxyObj = enhancer.create();
        // 返回代理对象
        return proxyObj;
    }

    @Override
    public Object intercept(Object proxy, Method method, Object[] args,
                            MethodProxy methodProxy) throws Throwable {
        Object obj = null;
        // 过滤方法
        if ("run".equals(method.getName())) {
            //System.out.println("enter proxy");
        }
        obj = method.invoke(targetObject, args);
        return obj;
    }

}

2、测试代码与结果:

我要测试的是两种动态代理方式生成代理对象与代理对象执行方法的耗时比较。

首先看生成代理对象的测试代码,我用循环去生成10000个代理对象,然后统计耗时:

       System.out.println("**********************CGLibProxy**********************");
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            CGLibProxy cgLibProxy = new CGLibProxy();
            Duck duckCGLib = (RedHeadDuck) cgLibProxy.createProxyObject(new RedHeadDuck());
        }
        long endTime = System.currentTimeMillis();
        System.out.println("CGLIB proxy generate obect spend:" + (endTime-startTime) + "ms");
        System.out.println("**********************JDKProxy**********************");
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            JDKProxy jdkPrpxy = new JDKProxy();
            Duck duckJDK = (Duck) jdkPrpxy.newProxy(new RedHeadDuck());
        }
        endTime = System.currentTimeMillis();
        System.out.println("JDK proxy generate object spend:" + (endTime-startTime) + "ms");

测试结果CGLib耗时约为JDK方式的两倍:

**********************CGLibProxy**********************
CGLIB proxy generate obect spend:24ms
**********************JDKProxy**********************
JDK proxy generate object spend:14ms

我们再来看对象执行的耗时:

测试代码:

        System.out.println("**********************CGLibProxy**********************");
        long startTime = System.currentTimeMillis();
        CGLibProxy cgLibProxy = new CGLibProxy();
        Duck duckCGLib = (RedHeadDuck) cgLibProxy.createProxyObject(new RedHeadDuck());
        for (int i = 0; i < 10000; i++) {
            duckCGLib.run("fast");
        }
        long endTime = System.currentTimeMillis();
        System.out.println("CGLIB proxy run obect spend:" + (endTime-startTime) + "ms");
        System.out.println("**********************JDKProxy**********************");
        startTime = System.currentTimeMillis();
        JDKProxy jdkPrpxy = new JDKProxy();
        Duck duckJDK = (Duck) jdkPrpxy.newProxy(new RedHeadDuck());
        for (int i = 0; i < 10000; i++) {
            duckJDK.run("fast");
        }
        endTime = System.currentTimeMillis();
        System.out.println("JDK proxy run object spend:" + (endTime-startTime) + "ms");

测试结果CGLib耗时依然更多,约两倍:

**********************CGLibProxy**********************
CGLIB proxy run obect spend:8ms
**********************JDKProxy**********************
JDK proxy run object spend:4ms

3、结论:

不知道是不是我的测试方法有问题,测试结果都是CGLib更慢,这与我在一些博客上看到的说法不一致,一些博客说CGlib产生对象较JDK方式慢,但是执行对象会更快,求大神解答!

你可能感兴趣的:(java)