美文网首页
态代理方案性能对比(转)

态代理方案性能对比(转)

作者: 西华子 | 来源:发表于2018-06-10 18:56 被阅读0次

    因服务框架需要用动态代理生成客户端接口的stub,所以做了一下性能评测,
    动态代理工具比较成熟的产品有:
    JDK自带的,ASM,CGLIB(基于ASM包装),JAVAASSIST,
    使用的版本分别为:
    JDK-1.6.0_18-b07, ASM-3.3, CGLIB-2.2, JAVAASSIST-3.11.0.GA

    (一) 测试结果:
    数据为执行三次,每次调用一千万次代理方法的结果,测试代码后面有贴出。

    (1) PC机测试结果:Linux 2.6.9-42.ELsmp(32bit), 2 Cores CPU(Intel Pentium4 3.06GHz)

    Create JDK Proxy: 13 ms  
    Create CGLIB Proxy: 217 ms  
    Create JAVAASSIST Proxy: 99 ms  
    Create JAVAASSIST Bytecode Proxy: 168 ms  
    Create ASM Proxy: 3 ms  
    ================  
    Run JDK Proxy: 2224 ms, 634,022 t/s  
    Run CGLIB Proxy: 1123 ms, 1,255,623 t/s  
    Run JAVAASSIST Proxy: 3212 ms, 438,999 t/s  
    Run JAVAASSIST Bytecode Proxy: 206 ms, 6,844,977 t/s  
    Run ASM Bytecode Proxy: 209 ms, 6,746,724 t/s  
    ----------------  
    Run JDK Proxy: 2169 ms, 650,099 t/s  
    Run CGLIB Proxy: 1059 ms, 1,331,506 t/s  
    Run JAVAASSIST Proxy: 3328 ms, 423,697 t/s  
    Run JAVAASSIST Bytecode Proxy: 202 ms, 6,980,521 t/s  
    Run ASM Bytecode Proxy: 206 ms, 6,844,977 t/s  
    ----------------  
    Run JDK Proxy: 2174 ms, 648,604 t/s  
    Run CGLIB Proxy: 1032 ms, 1,366,342 t/s  
    Run JAVAASSIST Proxy: 3119 ms, 452,088 t/s  
    Run JAVAASSIST Bytecode Proxy: 207 ms, 6,811,910 t/s  
    Run ASM Bytecode Proxy: 207 ms, 6,811,910 t/s  
    ----------------  
    

    (2) 服务器测试结果:Linux 2.6.18-128.el5xen(64bit), 16 Cores CPU(Intel Xeon E5520 2.27GHz)

    Create JDK Proxy: 7 ms  
    Create CGLIB Proxy: 86 ms  
    Create JAVAASSIST Proxy: 36 ms  
    Create JAVAASSIST Bytecode Proxy: 57 ms  
    Create ASM Proxy: 1 ms  
    ================  
    Run JDK Proxy: 235 ms, 6,000,278 t/s  
    Run CGLIB Proxy: 234 ms, 6,025,920 t/s  
    Run JAVAASSIST Proxy: 459 ms, 3,072,037 t/s  
    Run JAVAASSIST Bytecode Proxy: 71 ms, 19,860,076 t/s  
    Run ASM Bytecode Proxy: 72 ms, 19,584,241 t/s  
    ----------------  
    Run JDK Proxy: 298 ms, 4,731,763 t/s  
    Run CGLIB Proxy: 134 ms, 10,522,876 t/s  
    Run JAVAASSIST Proxy: 406 ms, 3,473,067 t/s  
    Run JAVAASSIST Bytecode Proxy: 67 ms, 21,045,752 t/s  
    Run ASM Bytecode Proxy: 66 ms, 21,364,627 t/s  
    ----------------  
    Run JDK Proxy: 282 ms, 5,000,231 t/s  
    Run CGLIB Proxy: 133 ms, 10,601,995 t/s  
    Run JAVAASSIST Proxy: 406 ms, 3,473,067 t/s  
    Run JAVAASSIST Bytecode Proxy: 67 ms, 21,045,752 t/s  
    Run ASM Bytecode Proxy: 67 ms, 21,045,752 t/s  
    ----------------  
    

    (二) 测试结论:

    1. ASM和JAVAASSIST字节码生成方式不相上下,都很快,是CGLIB的5倍。
    2. CGLIB次之,是JDK自带的两倍。
    3. JDK自带的再次之,因JDK1.6对动态代理做了优化,如果用低版本JDK更慢,要注意的是JDK也是通过字节码生成来实现动态代理的,而不是反射。
    4. JAVAASSIST提供者动态代理接口最慢,比JDK自带的还慢。
      (这也是为什么网上有人说JAVAASSIST比JDK还慢的原因,用JAVAASSIST最好别用它提供的动态代理接口,而可以考虑用它的字节码生成方式)

    (三) 差异原因:
    各方案生成的字节码不一样,
    像JDK和CGLIB都考虑了很多因素,以及继承或包装了自己的一些类,
    所以生成的字节码非常大,而我们很多时候用不上这些,
    而手工生成的字节码非常小,所以速度快,
    具体的字节码对比,后面有贴出,可自行分析。

    (四) 最终选型:
    最终决定使用JAVAASSIST的字节码生成代理方式,
    虽然ASM稍快,但并没有快一个数量级,
    而JAVAASSIST的字节码生成方式比ASM方便,
    JAVAASSIST只需用字符串拼接出Java源码,便可生成相应字节码,
    而ASM需要手工写字节码。

    (五) 测试代码:

    public interface CountService {  
      
        int count();  
      
    }  
    
    public class CountServiceImpl implements CountService {  
      
        private int count = 0;  
      
        public int count() {  
            return count ++;  
        }  
    }  
    
    
    import java.lang.reflect.Field;  
    import java.lang.reflect.InvocationHandler;  
    import java.lang.reflect.Method;  
    import java.lang.reflect.Proxy;  
    import java.text.DecimalFormat;  
      
    import javassist.ClassPool;  
    import javassist.CtClass;  
    import javassist.CtField;  
    import javassist.CtNewConstructor;  
    import javassist.CtNewMethod;  
    import javassist.util.proxy.MethodHandler;  
    import javassist.util.proxy.ProxyFactory;  
    import javassist.util.proxy.ProxyObject;  
    import net.sf.cglib.proxy.Enhancer;  
    import net.sf.cglib.proxy.MethodInterceptor;  
    import net.sf.cglib.proxy.MethodProxy;  
      
    import org.objectweb.asm.ClassWriter;  
    import org.objectweb.asm.FieldVisitor;  
    import org.objectweb.asm.MethodVisitor;  
    import org.objectweb.asm.Opcodes;  
      
    public class DynamicProxyPerformanceTest {  
      
        public static void main(String[] args) throws Exception {  
            CountService delegate = new CountServiceImpl();  
              
            long time = System.currentTimeMillis();  
            CountService jdkProxy = createJdkDynamicProxy(delegate);  
            time = System.currentTimeMillis() - time;  
            System.out.println("Create JDK Proxy: " + time + " ms");  
              
            time = System.currentTimeMillis();  
            CountService cglibProxy = createCglibDynamicProxy(delegate);  
            time = System.currentTimeMillis() - time;  
            System.out.println("Create CGLIB Proxy: " + time + " ms");  
              
            time = System.currentTimeMillis();  
            CountService javassistProxy = createJavassistDynamicProxy(delegate);  
            time = System.currentTimeMillis() - time;  
            System.out.println("Create JAVAASSIST Proxy: " + time + " ms");  
              
            time = System.currentTimeMillis();  
            CountService javassistBytecodeProxy = createJavassistBytecodeDynamicProxy(delegate);  
            time = System.currentTimeMillis() - time;  
            System.out.println("Create JAVAASSIST Bytecode Proxy: " + time + " ms");  
              
            time = System.currentTimeMillis();  
            CountService asmBytecodeProxy = createAsmBytecodeDynamicProxy(delegate);  
            time = System.currentTimeMillis() - time;  
            System.out.println("Create ASM Proxy: " + time + " ms");  
            System.out.println("================");  
              
            for (int i = 0; i < 3; i++) {  
                test(jdkProxy, "Run JDK Proxy: ");  
                test(cglibProxy, "Run CGLIB Proxy: ");  
                test(javassistProxy, "Run JAVAASSIST Proxy: ");  
                test(javassistBytecodeProxy, "Run JAVAASSIST Bytecode Proxy: ");  
                test(asmBytecodeProxy, "Run ASM Bytecode Proxy: ");  
                System.out.println("----------------");  
            }  
        }  
      
        private static void test(CountService service, String label)  
                throws Exception {  
            service.count(); // warm up  
            int count = 10000000;  
            long time = System.currentTimeMillis();  
            for (int i = 0; i < count; i++) {  
                service.count();  
            }  
            time = System.currentTimeMillis() - time;  
            System.out.println(label + time + " ms, " + new DecimalFormat().format(count * 1000 / time) + " t/s");  
        }  
      
        private static CountService createJdkDynamicProxy(final CountService delegate) {  
            CountService jdkProxy = (CountService) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),  
                    new Class[] { CountService.class }, new JdkHandler(delegate));  
            return jdkProxy;  
        }  
          
        private 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);  
            }  
        }  
      
        private static CountService createCglibDynamicProxy(final CountService delegate) throws Exception {  
            Enhancer enhancer = new Enhancer();  
            enhancer.setCallback(new CglibInterceptor(delegate));  
            enhancer.setInterfaces(new Class[] { CountService.class });  
            CountService cglibProxy = (CountService) enhancer.create();  
            return cglibProxy;  
        }  
      
        private 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);  
            }  
        }  
      
        private static CountService createJavassistDynamicProxy(final CountService delegate) throws Exception {  
            ProxyFactory proxyFactory = new ProxyFactory();  
            proxyFactory.setInterfaces(new Class[] { CountService.class });  
            Class<?> proxyClass = proxyFactory.createClass();  
            CountService javassistProxy = (CountService) proxyClass.newInstance();  
            ((ProxyObject) javassistProxy).setHandler(new JavaAssitInterceptor(delegate));  
            return javassistProxy;  
        }  
      
        private 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);  
            }  
        }  
      
        private static CountService createJavassistBytecodeDynamicProxy(CountService delegate) throws Exception {  
            ClassPool mPool = new ClassPool(true);  
            CtClass mCtc = mPool.makeClass(CountService.class.getName() + "JavaassistProxy");  
            mCtc.addInterface(mPool.get(CountService.class.getName()));  
            mCtc.addConstructor(CtNewConstructor.defaultConstructor(mCtc));  
            mCtc.addField(CtField.make("public " + CountService.class.getName() + " delegate;", mCtc));  
            mCtc.addMethod(CtNewMethod.make("public int count() { return delegate.count(); }", mCtc));  
            Class<?> pc = mCtc.toClass();  
            CountService bytecodeProxy = (CountService) pc.newInstance();  
            Field filed = bytecodeProxy.getClass().getField("delegate");  
            filed.set(bytecodeProxy, delegate);  
            return bytecodeProxy;  
        }  
          
        private static CountService createAsmBytecodeDynamicProxy(CountService delegate) throws Exception {  
            ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);  
            String className = CountService.class.getName() +  "AsmProxy";  
            String classPath = className.replace('.', '/');  
            String interfacePath = CountService.class.getName().replace('.', '/');  
            classWriter.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, classPath, null, "java/lang/Object", new String[] {interfacePath});  
              
            MethodVisitor initVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);  
            initVisitor.visitCode();  
            initVisitor.visitVarInsn(Opcodes.ALOAD, 0);  
            initVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");  
            initVisitor.visitInsn(Opcodes.RETURN);  
            initVisitor.visitMaxs(0, 0);  
            initVisitor.visitEnd();  
              
            FieldVisitor fieldVisitor = classWriter.visitField(Opcodes.ACC_PUBLIC, "delegate", "L" + interfacePath + ";", null, null);  
            fieldVisitor.visitEnd();  
              
            MethodVisitor methodVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "count", "()I", null, null);  
            methodVisitor.visitCode();  
            methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);  
            methodVisitor.visitFieldInsn(Opcodes.GETFIELD, classPath, "delegate", "L" + interfacePath + ";");  
            methodVisitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, interfacePath, "count", "()I");  
            methodVisitor.visitInsn(Opcodes.IRETURN);  
            methodVisitor.visitMaxs(0, 0);  
            methodVisitor.visitEnd();  
              
            classWriter.visitEnd();  
            byte[] code = classWriter.toByteArray();  
            CountService bytecodeProxy = (CountService) new ByteArrayClassLoader().getClass(className, code).newInstance();  
            Field filed = bytecodeProxy.getClass().getField("delegate");  
            filed.set(bytecodeProxy, delegate);  
            return bytecodeProxy;  
        }  
          
        private static class ByteArrayClassLoader extends ClassLoader {  
      
            public ByteArrayClassLoader() {  
                super(ByteArrayClassLoader.class.getClassLoader());  
            }  
      
            public synchronized Class<?> getClass(String name, byte[] code) {  
                if (name == null) {  
                    throw new IllegalArgumentException("");  
                }  
                return defineClass(name, code, 0, code.length);  
            }  
      
        }  
    }  
    

    (六) 字节码对比

    (1) JDK生成的字节码:

    public final class $Proxy0 extends java.lang.reflect.Proxy implements com.alibaba.test.performance.dynamicproxy.CountService{  
    public $Proxy0(java.lang.reflect.InvocationHandler)   throws ;  
      Code:  
       0:   aload_0  
       1:   aload_1  
       2:   invokespecial   #8; //Method java/lang/reflect/Proxy."":(Ljava/lang/reflect/InvocationHandler;)V  
       5:   return  
      
    public final boolean equals(java.lang.Object)   throws ;  
      Code:  
       0:   aload_0  
       1:   getfield    #16; //Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;  
       4:   aload_0  
       5:   getstatic   #20; //Field m1:Ljava/lang/reflect/Method;  
       8:   iconst_1  
       9:   anewarray   #22; //class java/lang/Object  
       12:  dup  
       13:  iconst_0  
       14:  aload_1  
       15:  aastore  
       16:  invokeinterface #28,  4; //InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
       21:  checkcast   #30; //class java/lang/Boolean  
       24:  invokevirtual   #34; //Method java/lang/Boolean.booleanValue:()Z  
       27:  ireturn  
       28:  athrow  
       29:  astore_2  
       30:  new #42; //class java/lang/reflect/UndeclaredThrowableException  
       33:  dup  
       34:  aload_2  
       35:  invokespecial   #45; //Method java/lang/reflect/UndeclaredThrowableException."":(Ljava/lang/Throwable;)V  
       38:  athrow  
      Exception table:  
       from   to  target type  
         0    28    28   Class java/lang/Error  
      
         0    28    28   Class java/lang/RuntimeException  
      
         0    28    29   Class java/lang/Throwable  
      
      
    public final int count()   throws ;  
      Code:  
       0:   aload_0  
       1:   getfield    #16; //Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;  
       4:   aload_0  
       5:   getstatic   #50; //Field m3:Ljava/lang/reflect/Method;  
       8:   aconst_null  
       9:   invokeinterface #28,  4; //InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
       14:  checkcast   #52; //class java/lang/Integer  
       17:  invokevirtual   #55; //Method java/lang/Integer.intValue:()I  
       20:  ireturn  
       21:  athrow  
       22:  astore_1  
       23:  new #42; //class java/lang/reflect/UndeclaredThrowableException  
       26:  dup  
       27:  aload_1  
       28:  invokespecial   #45; //Method java/lang/reflect/UndeclaredThrowableException."":(Ljava/lang/Throwable;)V  
       31:  athrow  
      Exception table:  
       from   to  target type  
         0    21    21   Class java/lang/Error  
      
         0    21    21   Class java/lang/RuntimeException  
      
         0    21    22   Class java/lang/Throwable  
      
      
    public final int hashCode()   throws ;  
      Code:  
       0:   aload_0  
       1:   getfield    #16; //Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;  
       4:   aload_0  
       5:   getstatic   #59; //Field m0:Ljava/lang/reflect/Method;  
       8:   aconst_null  
       9:   invokeinterface #28,  4; //InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
       14:  checkcast   #52; //class java/lang/Integer  
       17:  invokevirtual   #55; //Method java/lang/Integer.intValue:()I  
       20:  ireturn  
       21:  athrow  
       22:  astore_1  
       23:  new #42; //class java/lang/reflect/UndeclaredThrowableException  
       26:  dup  
       27:  aload_1  
       28:  invokespecial   #45; //Method java/lang/reflect/UndeclaredThrowableException."":(Ljava/lang/Throwable;)V  
       31:  athrow  
      Exception table:  
       from   to  target type  
         0    21    21   Class java/lang/Error  
      
         0    21    21   Class java/lang/RuntimeException  
      
         0    21    22   Class java/lang/Throwable  
      
      
    public final java.lang.String toString()   throws ;  
      Code:  
       0:   aload_0  
       1:   getfield    #16; //Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;  
       4:   aload_0  
       5:   getstatic   #64; //Field m2:Ljava/lang/reflect/Method;  
       8:   aconst_null  
       9:   invokeinterface #28,  4; //InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
       14:  checkcast   #66; //class java/lang/String  
       17:  areturn  
       18:  athrow  
       19:  astore_1  
       20:  new #42; //class java/lang/reflect/UndeclaredThrowableException  
       23:  dup  
       24:  aload_1  
       25:  invokespecial   #45; //Method java/lang/reflect/UndeclaredThrowableException."":(Ljava/lang/Throwable;)V  
       28:  athrow  
      Exception table:  
       from   to  target type  
         0    18    18   Class java/lang/Error  
      
         0    18    18   Class java/lang/RuntimeException  
      
         0    18    19   Class java/lang/Throwable  
      
      
    static {}   throws ;  
      Code:  
       0:   ldc #70; //String java.lang.Object  
       2:   invokestatic    #76; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;  
       5:   ldc #77; //String equals  
       7:   iconst_1  
       8:   anewarray   #72; //class java/lang/Class  
       11:  dup  
       12:  iconst_0  
       13:  ldc #70; //String java.lang.Object  
       15:  invokestatic    #76; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;  
       18:  aastore  
       19:  invokevirtual   #81; //Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;  
       22:  putstatic   #20; //Field m1:Ljava/lang/reflect/Method;  
       25:  ldc #83; //String com.alibaba.test.performance.dynamicproxy.CountService  
       27:  invokestatic    #76; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;  
       30:  ldc #84; //String count  
       32:  iconst_0  
       33:  anewarray   #72; //class java/lang/Class  
       36:  invokevirtual   #81; //Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;  
       39:  putstatic   #50; //Field m3:Ljava/lang/reflect/Method;  
       42:  ldc #70; //String java.lang.Object  
       44:  invokestatic    #76; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;  
       47:  ldc #85; //String hashCode  
       49:  iconst_0  
       50:  anewarray   #72; //class java/lang/Class  
       53:  invokevirtual   #81; //Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;  
       56:  putstatic   #59; //Field m0:Ljava/lang/reflect/Method;  
       59:  ldc #70; //String java.lang.Object  
       61:  invokestatic    #76; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;  
       64:  ldc #86; //String toString  
       66:  iconst_0  
       67:  anewarray   #72; //class java/lang/Class  
       70:  invokevirtual   #81; //Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;  
       73:  putstatic   #64; //Field m2:Ljava/lang/reflect/Method;  
       76:  return  
       77:  astore_1  
       78:  new #90; //class java/lang/NoSuchMethodError  
       81:  dup  
       82:  aload_1  
       83:  invokevirtual   #93; //Method java/lang/Throwable.getMessage:()Ljava/lang/String;  
       86:  invokespecial   #96; //Method java/lang/NoSuchMethodError."":(Ljava/lang/String;)V  
       89:  athrow  
       90:  astore_1  
       91:  new #100; //class java/lang/NoClassDefFoundError  
       94:  dup  
       95:  aload_1  
       96:  invokevirtual   #93; //Method java/lang/Throwable.getMessage:()Ljava/lang/String;  
       99:  invokespecial   #101; //Method java/lang/NoClassDefFoundError."":(Ljava/lang/String;)V  
       102: athrow  
      Exception table:  
       from   to  target type  
         0    77    77   Class java/lang/NoSuchMethodException  
      
         0    77    90   Class java/lang/ClassNotFoundException  
      
      
    }  
    

    (2) CGLIB生成的字节码:

    public class net.sf.cglib.core.MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7 extends net.sf.cglib.core.KeyFactory implements net.sf.cglib.core.MethodWrapper$MethodWrapperKey{  
    public net.sf.cglib.core.MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7();  
      Code:  
       0:   aload_0  
       1:   invokespecial   #11; //Method net/sf/cglib/core/KeyFactory."":()V  
       4:   return  
      
    public java.lang.Object newInstance(java.lang.String, java.lang.String[], java.lang.String);  
      Code:  
       0:   new #2; //class net/sf/cglib/core/MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7  
       3:   dup  
       4:   aload_1  
       5:   aload_2  
       6:   aload_3  
       7:   invokespecial   #16; //Method "":(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V  
       10:  areturn  
      
    public net.sf.cglib.core.MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7(java.lang.String, java.lang.String[], java.lang.String);  
      Code:  
       0:   aload_0  
       1:   invokespecial   #11; //Method net/sf/cglib/core/KeyFactory."":()V  
       4:   aload_0  
       5:   dup  
       6:   aload_1  
       7:   putfield    #20; //Field FIELD_0:Ljava/lang/String;  
       10:  dup  
       11:  aload_2  
       12:  putfield    #24; //Field FIELD_1:[Ljava/lang/String;  
       15:  dup  
       16:  aload_3  
       17:  putfield    #27; //Field FIELD_2:Ljava/lang/String;  
       20:  return  
      
    public int hashCode();  
      Code:  
       0:   ldc #30; //int 938313161  
       2:   aload_0  
       3:   getfield    #20; //Field FIELD_0:Ljava/lang/String;  
       6:   swap  
       7:   ldc #31; //int 362693231  
       9:   imul  
       10:  swap  
       11:  dup  
       12:  ifnull  21  
       15:  invokevirtual   #35; //Method java/lang/Object.hashCode:()I  
       18:  goto    23  
       21:  pop  
       22:  iconst_0  
       23:  iadd  
       24:  aload_0  
       25:  getfield    #24; //Field FIELD_1:[Ljava/lang/String;  
       28:  dup  
       29:  ifnull  71  
       32:  astore_1  
       33:  iconst_0  
       34:  istore_2  
       35:  goto    62  
       38:  aload_1  
       39:  iload_2  
       40:  aaload  
       41:  swap  
       42:  ldc #31; //int 362693231  
       44:  imul  
       45:  swap  
       46:  dup  
       47:  ifnull  56  
       50:  invokevirtual   #35; //Method java/lang/Object.hashCode:()I  
       53:  goto    58  
       56:  pop  
       57:  iconst_0  
       58:  iadd  
       59:  iinc    2, 1  
       62:  iload_2  
       63:  aload_1  
       64:  arraylength  
       65:  if_icmplt   38  
       68:  goto    72  
       71:  pop  
       72:  aload_0  
       73:  getfield    #27; //Field FIELD_2:Ljava/lang/String;  
       76:  swap  
       77:  ldc #31; //int 362693231  
       79:  imul  
       80:  swap  
       81:  dup  
       82:  ifnull  91  
       85:  invokevirtual   #35; //Method java/lang/Object.hashCode:()I  
       88:  goto    93  
       91:  pop  
       92:  iconst_0  
       93:  iadd  
       94:  ireturn  
      
    public boolean equals(java.lang.Object);  
      Code:  
       0:   aload_1  
       1:   instanceof  #2; //class net/sf/cglib/core/MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7  
       4:   ifeq    181  
       7:   aload_0  
       8:   getfield    #20; //Field FIELD_0:Ljava/lang/String;  
       11:  aload_1  
       12:  checkcast   #2; //class net/sf/cglib/core/MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7  
       15:  getfield    #20; //Field FIELD_0:Ljava/lang/String;  
       18:  dup2  
       19:  ifnonnull   29  
       22:  ifnonnull   35  
       25:  pop2  
       26:  goto    45  
       29:  ifnull  35  
       32:  goto    39  
       35:  pop2  
       36:  goto    181  
       39:  invokevirtual   #39; //Method java/lang/Object.equals:(Ljava/lang/Object;)Z  
       42:  ifeq    181  
       45:  aload_0  
       46:  getfield    #24; //Field FIELD_1:[Ljava/lang/String;  
       49:  aload_1  
       50:  checkcast   #2; //class net/sf/cglib/core/MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7  
       53:  getfield    #24; //Field FIELD_1:[Ljava/lang/String;  
       56:  dup2  
       57:  ifnonnull   67  
       60:  ifnonnull   73  
       63:  pop2  
       64:  goto    141  
       67:  ifnull  73  
       70:  goto    77  
       73:  pop2  
       74:  goto    181  
       77:  dup2  
       78:  arraylength  
       79:  swap  
       80:  arraylength  
       81:  if_icmpeq   88  
       84:  pop2  
       85:  goto    181  
       88:  astore_2  
       89:  astore_3  
       90:  iconst_0  
       91:  istore  4  
       93:  goto    134  
       96:  aload_2  
       97:  iload   4  
       99:  aaload  
       100: aload_3  
       101: iload   4  
       103: aaload  
       104: dup2  
       105: ifnonnull   115  
       108: ifnonnull   121  
       111: pop2  
       112: goto    131  
       115: ifnull  121  
       118: goto    125  
       121: pop2  
       122: goto    181  
       125: invokevirtual   #39; //Method java/lang/Object.equals:(Ljava/lang/Object;)Z  
       128: ifeq    181  
       131: iinc    4, 1  
       134: iload   4  
       136: aload_2  
       137: arraylength  
       138: if_icmplt   96  
       141: aload_0  
       142: getfield    #27; //Field FIELD_2:Ljava/lang/String;  
       145: aload_1  
       146: checkcast   #2; //class net/sf/cglib/core/MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7  
       149: getfield    #27; //Field FIELD_2:Ljava/lang/String;  
       152: dup2  
       153: ifnonnull   163  
       156: ifnonnull   169  
       159: pop2  
       160: goto    179  
       163: ifnull  169  
       166: goto    173  
       169: pop2  
       170: goto    181  
       173: invokevirtual   #39; //Method java/lang/Object.equals:(Ljava/lang/Object;)Z  
       176: ifeq    181  
       179: iconst_1  
       180: ireturn  
       181: iconst_0  
       182: ireturn  
      
    public java.lang.String toString();  
      Code:  
       0:   new #43; //class java/lang/StringBuffer  
       3:   dup  
       4:   invokespecial   #44; //Method java/lang/StringBuffer."":()V  
       7:   aload_0  
       8:   getfield    #20; //Field FIELD_0:Ljava/lang/String;  
       11:  dup  
       12:  ifnull  24  
       15:  invokevirtual   #46; //Method java/lang/Object.toString:()Ljava/lang/String;  
       18:  invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
       21:  goto    30  
       24:  pop  
       25:  ldc #52; //String null  
       27:  invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
       30:  ldc #54; //String ,   
       32:  invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
       35:  aload_0  
       36:  getfield    #24; //Field FIELD_1:[Ljava/lang/String;  
       39:  dup  
       40:  ifnull  110  
       43:  swap  
       44:  ldc #56; //String {  
       46:  invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
       49:  swap  
       50:  astore_1  
       51:  iconst_0  
       52:  istore_2  
       53:  goto    86  
       56:  aload_1  
       57:  iload_2  
       58:  aaload  
       59:  dup  
       60:  ifnull  72  
       63:  invokevirtual   #46; //Method java/lang/Object.toString:()Ljava/lang/String;  
       66:  invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
       69:  goto    78  
       72:  pop  
       73:  ldc #52; //String null  
       75:  invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
       78:  ldc #54; //String ,   
       80:  invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
       83:  iinc    2, 1  
       86:  iload_2  
       87:  aload_1  
       88:  arraylength  
       89:  if_icmplt   56  
       92:  dup  
       93:  dup  
       94:  invokevirtual   #59; //Method java/lang/StringBuffer.length:()I  
       97:  iconst_2  
       98:  isub  
       99:  invokevirtual   #63; //Method java/lang/StringBuffer.setLength:(I)V  
       102: ldc #65; //String }  
       104: invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
       107: goto    116  
       110: pop  
       111: ldc #52; //String null  
       113: invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
       116: ldc #54; //String ,   
       118: invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
       121: aload_0  
       122: getfield    #27; //Field FIELD_2:Ljava/lang/String;  
       125: dup  
       126: ifnull  138  
       129: invokevirtual   #46; //Method java/lang/Object.toString:()Ljava/lang/String;  
       132: invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
       135: goto    144  
       138: pop  
       139: ldc #52; //String null  
       141: invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
       144: invokevirtual   #66; //Method java/lang/StringBuffer.toString:()Ljava/lang/String;  
       147: areturn  
      
    }  
    

    (3) JAVAASSIST动态代理接口生成的字节码:

    public class com.alibaba.test.performance.dynamicproxy.CountService_$$_javassist_0 extends java.lang.Object implements com.alibaba.test.performance.dynamicproxy.CountService,javassist.util.proxy.ProxyObject{  
    public static javassist.util.proxy.MethodHandler default_interceptor;  
      
    public static javassist.util.proxy.MethodFilter _method_filter;  
      
    public com.alibaba.test.performance.dynamicproxy.CountService_$$_javassist_0();  
      Code:  
       0:   aload_0  
       1:   getstatic   #19; //Field default_interceptor:Ljavassist/util/proxy/MethodHandler;  
       4:   putfield    #21; //Field handler:Ljavassist/util/proxy/MethodHandler;  
       7:   getstatic   #23; //Field default_interceptor:Ljavassist/util/proxy/MethodHandler;  
       10:  ifnonnull   20  
       13:  aload_0  
       14:  getstatic   #27; //Field javassist/util/proxy/RuntimeSupport.default_interceptor:Ljavassist/util/proxy/MethodHandler;  
       17:  putfield    #29; //Field handler:Ljavassist/util/proxy/MethodHandler;  
       20:  aload_0  
       21:  invokespecial   #31; //Method java/lang/Object."":()V  
       24:  return  
      
    public final boolean _d0equals(java.lang.Object);  
      Code:  
       0:   aload_0  
       1:   aload_1  
       2:   invokespecial   #38; //Method java/lang/Object.equals:(Ljava/lang/Object;)Z  
       5:   ireturn  
      
    public final boolean equals(java.lang.Object);  
      Code:  
       0:   getstatic   #42; //Field _methods_:[Ljava/lang/reflect/Method;  
       3:   astore_2  
       4:   aload_0  
       5:   ldc #43; //String equals  
       7:   ldc #44; //String _d0equals  
       9:   iconst_0  
       10:  ldc #45; //String (Ljava/lang/Object;)Z  
       12:  aload_2  
       13:  invokestatic    #49; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V  
       16:  aload_0  
       17:  getfield    #51; //Field handler:Ljavassist/util/proxy/MethodHandler;  
       20:  aload_0  
       21:  aload_2  
       22:  iconst_0  
       23:  aaload  
       24:  aload_2  
       25:  iconst_1  
       26:  aaload  
       27:  iconst_1  
       28:  anewarray   #52; //class java/lang/Object  
       31:  dup  
       32:  iconst_0  
       33:  aload_1  
       34:  aastore  
       35:  invokeinterface #58,  5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
       40:  checkcast   #60; //class java/lang/Boolean  
       43:  invokevirtual   #64; //Method java/lang/Boolean.booleanValue:()Z  
       46:  ireturn  
      
    public final java.lang.Object _d1clone()   throws java.lang.CloneNotSupportedException;  
      Code:  
       0:   aload_0  
       1:   invokespecial   #72; //Method java/lang/Object.clone:()Ljava/lang/Object;  
       4:   areturn  
      
    protected final java.lang.Object clone()   throws java.lang.CloneNotSupportedException;  
      Code:  
       0:   getstatic   #74; //Field _methods_:[Ljava/lang/reflect/Method;  
       3:   astore_1  
       4:   aload_0  
       5:   ldc #75; //String clone  
       7:   ldc #76; //String _d1clone  
       9:   iconst_2  
       10:  ldc #77; //String ()Ljava/lang/Object;  
       12:  aload_1  
       13:  invokestatic    #79; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V  
       16:  aload_0  
       17:  getfield    #81; //Field handler:Ljavassist/util/proxy/MethodHandler;  
       20:  aload_0  
       21:  aload_1  
       22:  iconst_2  
       23:  aaload  
       24:  aload_1  
       25:  iconst_3  
       26:  aaload  
       27:  iconst_0  
       28:  anewarray   #52; //class java/lang/Object  
       31:  invokeinterface #83,  5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
       36:  checkcast   #4; //class java/lang/Object  
       39:  areturn  
      
    public final int _d2hashCode();  
      Code:  
       0:   aload_0  
       1:   invokespecial   #88; //Method java/lang/Object.hashCode:()I  
       4:   ireturn  
      
    public final int hashCode();  
      Code:  
       0:   getstatic   #90; //Field _methods_:[Ljava/lang/reflect/Method;  
       3:   astore_1  
       4:   aload_0  
       5:   ldc #91; //String hashCode  
       7:   ldc #92; //String _d2hashCode  
       9:   iconst_4  
       10:  ldc #93; //String ()I  
       12:  aload_1  
       13:  invokestatic    #95; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V  
       16:  aload_0  
       17:  getfield    #97; //Field handler:Ljavassist/util/proxy/MethodHandler;  
       20:  aload_0  
       21:  aload_1  
       22:  iconst_4  
       23:  aaload  
       24:  aload_1  
       25:  iconst_5  
       26:  aaload  
       27:  iconst_0  
       28:  anewarray   #52; //class java/lang/Object  
       31:  invokeinterface #99,  5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
       36:  checkcast   #101; //class java/lang/Integer  
       39:  invokevirtual   #104; //Method java/lang/Integer.intValue:()I  
       42:  ireturn  
      
    public final int count();  
      Code:  
       0:   getstatic   #107; //Field _methods_:[Ljava/lang/reflect/Method;  
       3:   astore_1  
       4:   aload_0  
       5:   ldc #108; //String count  
       7:   aconst_null  
       8:   bipush  6  
       10:  ldc #109; //String ()I  
       12:  aload_1  
       13:  invokestatic    #111; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V  
       16:  aload_0  
       17:  getfield    #113; //Field handler:Ljavassist/util/proxy/MethodHandler;  
       20:  aload_0  
       21:  aload_1  
       22:  bipush  6  
       24:  aaload  
       25:  aload_1  
       26:  bipush  7  
       28:  aaload  
       29:  iconst_0  
       30:  anewarray   #52; //class java/lang/Object  
       33:  invokeinterface #115,  5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
       38:  checkcast   #101; //class java/lang/Integer  
       41:  invokevirtual   #117; //Method java/lang/Integer.intValue:()I  
       44:  ireturn  
      
    public final void _d4finalize()   throws java.lang.Throwable;  
      Code:  
       0:   aload_0  
       1:   invokespecial   #123; //Method java/lang/Object.finalize:()V  
       4:   return  
      
    protected final void finalize()   throws java.lang.Throwable;  
      Code:  
       0:   getstatic   #125; //Field _methods_:[Ljava/lang/reflect/Method;  
       3:   astore_1  
       4:   aload_0  
       5:   ldc #126; //String finalize  
       7:   ldc #127; //String _d4finalize  
       9:   bipush  8  
       11:  ldc #128; //String ()V  
       13:  aload_1  
       14:  invokestatic    #130; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V  
       17:  aload_0  
       18:  getfield    #132; //Field handler:Ljavassist/util/proxy/MethodHandler;  
       21:  aload_0  
       22:  aload_1  
       23:  bipush  8  
       25:  aaload  
       26:  aload_1  
       27:  bipush  9  
       29:  aaload  
       30:  iconst_0  
       31:  anewarray   #52; //class java/lang/Object  
       34:  invokeinterface #134,  5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
       39:  pop  
       40:  return  
      
    public final java.lang.String _d5toString();  
      Code:  
       0:   aload_0  
       1:   invokespecial   #139; //Method java/lang/Object.toString:()Ljava/lang/String;  
       4:   areturn  
      
    public final java.lang.String toString();  
      Code:  
       0:   getstatic   #141; //Field _methods_:[Ljava/lang/reflect/Method;  
       3:   astore_1  
       4:   aload_0  
       5:   ldc #142; //String toString  
       7:   ldc #143; //String _d5toString  
       9:   bipush  10  
       11:  ldc #144; //String ()Ljava/lang/String;  
       13:  aload_1  
       14:  invokestatic    #146; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V  
       17:  aload_0  
       18:  getfield    #148; //Field handler:Ljavassist/util/proxy/MethodHandler;  
       21:  aload_0  
       22:  aload_1  
       23:  bipush  10  
       25:  aaload  
       26:  aload_1  
       27:  bipush  11  
       29:  aaload  
       30:  iconst_0  
       31:  anewarray   #52; //class java/lang/Object  
       34:  invokeinterface #150,  5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
       39:  checkcast   #152; //class java/lang/String  
       42:  areturn  
      
    static {};  
      Code:  
       0:   bipush  12  
       2:   anewarray   #155; //class java/lang/reflect/Method  
       5:   putstatic   #157; //Field _methods_:[Ljava/lang/reflect/Method;  
       8:   return  
      
    public void setHandler(javassist.util.proxy.MethodHandler);  
      Code:  
       0:   aload_0  
       1:   aload_1  
       2:   putfield    #161; //Field handler:Ljavassist/util/proxy/MethodHandler;  
       5:   return  
      
    java.lang.Object writeReplace()   throws java.io.ObjectStreamException;  
      Code:  
       0:   aload_0  
       1:   invokestatic    #168; //Method javassist/util/proxy/RuntimeSupport.makeSerializedProxy:(Ljava/lang/Object;)Ljavassist/util/proxy/SerializedProxy;  
       4:   areturn  
      
    }  
    
    

    (5) JAVAASSIST拼接源码生成的字节码:

    public class com.alibaba.test.performance.dynamicproxy.CountServiceJavaassistProxy extends java.lang.Object implements com.alibaba.test.performance.dynamicproxy.CountService{  
    public com.alibaba.test.performance.dynamicproxy.CountService delegate;  
      
    public com.alibaba.test.performance.dynamicproxy.CountServiceJavaassistProxy();  
      Code:  
       0:   aload_0  
       1:   invokespecial   #12; //Method java/lang/Object."":()V  
       4:   return  
      
    public int count();  
      Code:  
       0:   aload_0  
       1:   getfield    #19; //Field delegate:Lcom/alibaba/test/performance/dynamicproxy/CountService;  
       4:   invokeinterface #21,  1; //InterfaceMethod com/alibaba/test/performance/dynamicproxy/CountService.count:()I  
       9:   ireturn  
      
    }  
    

    (6) 用ASM自行生成的字节码:

    public class com.alibaba.test.performance.dynamicproxy.CountServiceAsmProxy extends java.lang.Object implements com.alibaba.test.performance.dynamicproxy.CountService{  
    public com.alibaba.test.performance.dynamicproxy.CountService delegate;  
      
    public com.alibaba.test.performance.dynamicproxy.CountServiceAsmProxy();  
      Code:  
       0:   aload_0  
       1:   invokespecial   #10; //Method java/lang/Object."":()V  
       4:   return  
      
    public int count();  
      Code:  
       0:   aload_0  
       1:   getfield    #16; //Field delegate:Lcom/alibaba/test/performance/dynamicproxy/CountService;  
       4:   invokeinterface #18,  1; //InterfaceMethod com/alibaba/test/performance/dynamicproxy/CountService.count:()I  
       9:   ireturn  
      
    }  
    

    相关文章

      网友评论

          本文标题:态代理方案性能对比(转)

          本文链接:https://www.haomeiwen.com/subject/rvkqeftx.html