好记性不如烂笔头48-java拦截器-JDK自带动态代理和CGLIB效率比较(3)

来源:互联网 发布:windows隐藏窗口样式 编辑:程序博客网 时间:2024/06/05 07:59

Java中自带的动态代理的类必须要实现一个接口,而且据说使用反射的效率也并不是很高。于是CGLIB就诞生了。
使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,理论上比使用Java反射效率要高。
那么我们测试下,这个运行的效率如何。
1、 测试的准备情况
准备1:好记性不如烂笔头46-java拦截器-彻底理解动态代理的概念(1) http://blog.csdn.net/ffm83/article/details/43699619
准备2: 好记性不如烂笔头47-java拦截器-用CGLib实现动态代理(2)
http://blog.csdn.net/ffm83/article/details/43702321

为了测试结果方便观察,把所有的打印输出关闭。
JDK版本: jdk1.6.0_25

2、 测试运行效率的源代码

package com.tools;import com.CGLib.WangBaoQiang;import com.proxy.Actor;/** * 使用预热模式 * JVM参数:-XX:PrintCompilation * @author 范芳铭 */public class BaseRun_Proxy_Test {    public static void main(String[] args) throws Exception{        int warmUpCycles = 1000000; //预热次数        BaseRun_Proxy_Test se = new BaseRun_Proxy_Test();        System.out.println("预热循环开始 ...");        se.runTest(warmUpCycles);        System.out.println("预热结束");        Thread.sleep(1000); //让系统暂停        System.out.println("进入正式循环 ...");        se.runTest(1);        se.runTest(100);        se.runTest(10000);        se.runTest(1000000);        se.runTest(20000000); //2000千万次,我们系统一天的访问量        System.out.println("正式运算完成");    }    private void runTest(int iterations){        BaseRun_Proxy_Test lot = new BaseRun_Proxy_Test();        //运行JAVA自带动态代理        long startTime = System.nanoTime();        for(int i = 0 ; i < iterations ;  i ++){            lot.getJavaProxyLoop();        }        long elapsedTime = System.nanoTime();        System.out.println("运行JAVA自带动态代理:" + iterations + ",结束,耗时:" + (elapsedTime-startTime));        //运行CGLIB        long cglibStartTime = System.nanoTime();        for(int i = 0 ; i < iterations ;  i ++){            lot.getCGLibLoop();        }        long cglibElapsedTime = System.nanoTime();        System.out.println("运行CGLIB动态代理:" + iterations + ",结束,耗时:" + (cglibElapsedTime-cglibStartTime));    }    public void getJavaProxyLoop(){        // 首先找到经纪人        com.proxy.ActorJingJiRen proxy = new com.proxy.ActorJingJiRen();        // 通过经纪人获得相关演员(代理对象)        Actor p = proxy.getProxy();        String retValue = p.sing("天下无贼");        String value = p.dance("凤凰传奇");    }    public void getCGLibLoop(){        com.CGLib.ActorJingJiRen proxy = new com.CGLib.ActorJingJiRen();        // 通过经纪人获得相关演员(代理对象)        WangBaoQiang p = proxy.getProxy();        String retValue = p.sing("天下无贼");        String value = p.dance("凤凰传奇");    }}

3、 运行结果
预热循环开始 …
运行JAVA自带动态代理:1000000,结束,耗时:2390557348
运行CGLIB动态代理:1000000,结束,耗时:6111703990
预热结束
进入正式循环 …
运行JAVA自带动态代理:1,结束,耗时:35715
运行CGLIB动态代理:1,结束,耗时:39409
运行JAVA自带动态代理:100,结束,耗时:381782
运行CGLIB动态代理:100,结束,耗时:1162997
运行JAVA自带动态代理:10000,结束,耗时:23943050
运行CGLIB动态代理:10000,结束,耗时:58153974
运行JAVA自带动态代理:1000000,结束,耗时:2403822826
运行CGLIB动态代理:1000000,结束,耗时:5804202226
运行JAVA自带动态代理:20000000,结束,耗时:48913882774
运行CGLIB动态代理:20000000,结束,耗时:118967606438
正式运算完成

4、 运行效率的表格

运行耗时对比

CGlib的动态代理的效率,看起来比JAVA自带的效率要低。这个和我们所听到的情况可能不一样。

5、 其他
将CGLIB放在java自带proxy的方法之前,数据情况和上面基本一致。

1 0
原创粉丝点击