码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-02-11 10:55:50      阅读:586      评论:0      收藏:0      [点我收藏+]

标签:接口   动态代理   反射   测试对比   

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的方法之前,数据情况和上面基本一致。

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

标签:接口   动态代理   反射   测试对比   

原文地址:http://blog.csdn.net/ffm83/article/details/43730861

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!