Java的动态编译 cglib / asm 等

http://www.qqread.com/netbase/w478517.html 

菜鸟课堂:几个动态代理Proxy工具性能比较


JDK 6和CGLib cglib-nodep-2.2.jar对比结果:


JDK Proxy: 1,049,937 calls/s


CGLIB: 2,820,130 calls/s


如果使用cglib以前版本,性能更快:


JDK Proxy: 1,037,575 calls/s


CGLIB: 3,112,727 calls/s


而JDK 6和JavaAssit 3.11测试结果如下:


JDK Proxy: 1,037,575 calls/s


JAVAASSIST: 626,695 calls/s 

 

从数据上看,cglib性能最好。但是和ASM、直接调用比较还不知道。 

代码
public   class  ProxyPerformanceComparison2 {

public   static   void  main(String[] args)  throws  Exception {

Callable
< integer >  jdkProxy  =  (Callable < integer > )

Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), 
new  Class[] {

Callable.
class  },

new  JdkHandler( new  Counter()));

ProxyFactory f 
=   new  ProxyFactory();

f.setInterfaces(
new  Class[] { Callable. class  });

Class c 
=  f.createClass();

Callable
< integer >  cglibProxy  =  (Callable < integer > ) c.newInstance();

((ProxyObject) cglibProxy).setHandler

(
new  JavaAssitInterceptor( new  Counter()));

for  ( int  i2  =   0 ; i2  <   10 ; i2 ++ ) {

iterate(jdkProxy, 
" JDK Proxy:  " );

iterate(cglibProxy, 
" JAVAASSIST:  " );

System.err.println();

}

}

static   final  DecimalFormat format  =   new  DecimalFormat();

static   void  iterate(Callable < integer >  callable, String label)

throws  Exception {

int  count  =   10000000 ;

long  time  =  System.currentTimeMillis();

int  total  =   0 ;

for  ( int  i  =   0 ; i  <  count; i ++ ) {

total 
+=  callable.call();

}

time 
=  System.currentTimeMillis()  -  time;

System.err.println(label 
+  format.format

(count 
*   1000   /  time)  +   "  calls/s " );

}

static   class  JdkHandler  implements  InvocationHandler {

final  Object delegate;

JdkHandler(Object delegate) {

this .delegate  =  delegate;

}

public  Object invoke

(Object object, Method method, Object[] objects) 
throws  Throwable {

return  method.invoke(delegate, objects);

}

}

static   class  JavaAssitInterceptor  implements  MethodHandler {

final  Object delegate;

JavaAssitInterceptor(Object delegate) {

this .delegate  =  delegate;

}

public  Object invoke

(Object self, Method m, Method proceed, Object[] args) 
throws  Throwable {

return  m.invoke(delegate, args);

}

}

static   class  Counter  implements  Callable < integer >  {

int  count  =   0 ;

public  Integer call()  throws  Exception {

return  count ++ ;

}

}

}

   

---------------------------------------------  

http://www.zx2010.com/program/java-jdk-cglib-proxy-performance-comparison.asp 

JDK动态代理与CGLIB代理的性能测试

result:


JDK Proxy: 765,092 calls/s

CGLIB:     1,503,268 calls/s


JDK Proxy: 716,132 calls/s

CGLIB:     991,607 calls/s


JDK Proxy: 601,820 calls/s

CGLIB:     1,128,052 calls/s 

结果也仅仅说明了cglib性能提高了2倍左右。还是不行。 

代码
import  java.lang.reflect. * ;
import  net.sf.cglib.proxy. * ;
import  java.text. * ;
import  java.util.concurrent.Callable;

public   class  ProxyPerformanceComparison {  
  
public   static   void  main(String[] args)  throws  Exception {    
    Callable
< Integer >  jdkProxy  =  (Callable < Integer > ) java.lang.reflect.Proxy.newProxyInstance(       
                                  ClassLoader.getSystemClassLoader(),
                                  
new  Class[] { Callable. class  },       
                                  
new  JdkHandler( new  Counter())    
                                  );    
    Enhancer enhancer 
=   new  Enhancer();    
    enhancer.setCallback(
new  CglibInterceptor( new  Counter()));    
    enhancer.setInterfaces(
new  Class[] { Callable. class  });    
    Callable
< Integer >  cglibProxy  =  (Callable < Integer > ) enhancer.create();  

    
for  ( int  i2  =   0 ; i2  <   10 ; i2 ++ ) {      
        iterate(jdkProxy,    
" JDK Proxy:  " );   
        iterate(cglibProxy,  
" CGLIB:      " );
        System.err.println();
    }
  } 

  
static   final  DecimalFormat format  =   new  DecimalFormat();

  
static   void  iterate(Callable < Integer >  callable, String label)   throws  Exception {
    
int  count  =   10000000 ;  
    
long  time  =  System.currentTimeMillis();  
    
int  total  =   0 ;   
    
for  ( int  i  =   0 ; i  <  count; i ++ ) {   
        total 
+=  callable.call(); 
    }    
    time 
=  System.currentTimeMillis()  -  time;    
    System.err.println(label  
+  format.format(count  *   1000   /  time)  +   "  calls/s " );  } 

    
/*  inner class  */
    
static   class  JdkHandler  implements  java.lang.reflect.InvocationHandler {   
      
final  Object delegate;    
      JdkHandler(Object delegate) {      
        
this .delegate  =  delegate;    
      }   
      
public  Object invoke(Object object, Method method, Object[] objects)  throws  Throwable {
         
return  method.invoke(delegate, objects);    
      }
    } 

    
/*  inner class  */
    
static   class  CglibInterceptor  implements  MethodInterceptor {   
      
final  Object delegate;   

      CglibInterceptor(Object delegate) {     
        
this .delegate  =  delegate;    
      }    
    
      
public  Object intercept(Object object, Method method, Object[] objects, MethodProxy methodProxy)  throws  Throwable {      
        
return  methodProxy.invoke(delegate, objects);   
      }
    }

    
/*  inner class  */
    
static   class  Counter  implements  Callable < Integer >  {    
      
int  count  =   0 ;
      
public  Integer call()  throws  Exception {
        
return  count ++ ;    
      } 
    }
}

 

 

------------------------------

http://www.javaeye.com/topic/314894

10000次对象复制测试结果(ms): 

task 直接复制                  31 

task java标准反射复制          610 

task cglib Fast复制(不好的写法) 890 

task cglib beancopier复制    125

使用beancopy,意思是把第一个bean的数据copy到第二个。貌似没有什么用。是2个对象之间复制。 

=  clazz0.newInstance();  
BeanCopier beanCopier 
=  BeanCopier.create(clazz0, managelogVO.getClass(),  false );  
beanCopier.copy(o,managelogVO, 
null );  

 

直接调用 

ManagelogVO newVO  =   new  ManagelogVO();  
    newVO.setLogid(managelogVO.getLogid());  
    newVO.setOprcode(managelogVO.getOprcode());  

 

Java反射

代码
Object o   =   null ;  
        
try  {  
            Class clazz 
=  Class.forName( " demo.cglib.ManagelogVO " );  
            o 
=  clazz.newInstance();  
            Method setterMethod 
=   null ;  
            Method getterMethod 
=   null ;  
            Object v 
=   null ;  
              
            setterMethod 
=  clazz.getMethod( " setLogid " new  Class[]{Long. class });  
            getterMethod 
=  clazz.getMethod( " getLogid " null );             
            v 
=  getterMethod.invoke(managelogVO,  null );  
            setterMethod.invoke(o, 
new  Object[]{v});  
              
            setterMethod 
=  clazz.getMethod( " setOprcode " new  Class[]{String. class });  
            getterMethod 
=  clazz.getMethod( " getOprcode " null );           
            v 
=  getterMethod.invoke(managelogVO,  null );  
            setterMethod.invoke(o, 
new  Object[]{v});  

 

cglib反射

代码
Object o   =   null ;  
try  {  
    Class clazz0 
=  Class.forName( " demo.cglib.ManagelogVO " );  
              
    FastClass clazz 
=  FastClass.create(clazz0);           
    o 
=  clazz.newInstance();  
    FastMethod setterMethod 
=   null ;  
    FastMethod getterMethod 
=   null ;  
    Object v 
=   null ;  
      
    setterMethod 
=  clazz.getMethod( " setLogid " new  Class[]{Long. class });  
    getterMethod 
=  clazz.getMethod( " getLogid " null );             
    v 
=  getterMethod.invoke(managelogVO,  new  Object[]{});  
    setterMethod.invoke(o, 
new  Object[]{v});  
      
    setterMethod 
=  clazz.getMethod( " setOprcode " new  Class[]{String. class });  
    getterMethod 
=  clazz.getMethod( " getOprcode " null );           
    v 
=  getterMethod.invoke(managelogVO,  new  Object[]{});  
    setterMethod.invoke(o, 
new  Object[]{v});  

 

 

---------------------------

http://www.ibm.com/developerworks/cn/java/j-lo-asm30/index.html

使用asm实现AOP

 

http://www.oschina.net/bbs/thread/4239

cglib的例子

 

 

你可能感兴趣的:(cglib)