zoukankan      html  css  js  c++  java
  • 自制DynamicProxy开发成功,性能测试提升了1.4倍。(看来微软的realproxy并不弱!导致我无法提升一个数量级)


    参考了微软的realproxy设计模式,使用相同的IMessage结构,重写了整个proxy。

    使用了emit技术,性能得到了极大提升。

    模仿旧的pojo代码,得到: 

    代码
        class MyProxy<T> : DynamicProxy
        {
            Dictionary
    <stringobject> dict = new Dictionary<stringobject>();

            
    public MyProxy()
                : 
    base(typeof(T))
            {
            }

            
    public T Value
            {
                
    get
                {
                    
    return (T)base.GetTransparentProxy();
                }
            }

            
    public override IDynamicMethodReturnMessage Invoke(IDynamicMethodCallMessage msg)
            {
                
    string methodname = msg.MethodInfo.Name.Trim().ToUpper();

                
    if (methodname.StartsWith("GET_"))
                    
    return InvokeGetter(msg);

                
    if (methodname.StartsWith("SET_"))
                    
    return InvokeSetter(msg);

                
    return base.CreateReturnMessage(new Exception("only support property."), msg);
            }

            
    private IDynamicMethodReturnMessage InvokeGetter(IDynamicMethodCallMessage methodCall)
            {
                IDummyMethodInfo method 
    = methodCall.MethodInfo;

                
    string invokeid = GetInvokeMessageId(method);

                
    if (dict.ContainsKey(invokeid))
                {
                    
    return base.CreateReturnMessage(dict[invokeid], methodCall);
                }

                
    if (method.ReturnType.PropertyType == DotNetPropertyType.Enum)
                {
                    
    return base.CreateReturnMessage(0, methodCall);
                }

                
    switch (Pixysoft.Tools.ParserHelper.GetDataTypeByTypeName(method.ReturnType.Name))
                {
                    
    case DotNetDataType.Boolean:
                        {
                            
    return base.CreateReturnMessage(false, methodCall);
                        }

                    
    case DotNetDataType.Byte:
                        {
                            
    return base.CreateReturnMessage(byte.MinValue, methodCall);
                        }

                    
    case DotNetDataType.Char:
                        {
                            
    return base.CreateReturnMessage(char.MinValue, methodCall);
                        }

                    
    case DotNetDataType.DateTime:
                        {
                            
    return base.CreateReturnMessage(DateTime.MinValue, methodCall);
                        }

                    
    case DotNetDataType.Decimal:
                        {
                            
    return base.CreateReturnMessage(decimal.MinValue, methodCall);
                        }
                    
    case DotNetDataType.Double:
                        {
                            
    return base.CreateReturnMessage(double.MinValue, methodCall);
                        }
                    
    case DotNetDataType.Int32:
                        {
                            
    return base.CreateReturnMessage(int.MinValue, methodCall);
                        }
                    
    case DotNetDataType.Int64:
                        {
                            
    return base.CreateReturnMessage(Int32.MinValue, methodCall);
                        }
                    
    case DotNetDataType.Single:
                        {
                            
    return base.CreateReturnMessage(Single.MinValue, methodCall);
                        }
                    
    case DotNetDataType.String:
                    
    case DotNetDataType.UNKNOWN:
                    
    default:
                        {
                            
    return base.CreateReturnMessage(null, methodCall);
                        }
                }

            }

            
    private IDynamicMethodReturnMessage InvokeSetter(IDynamicMethodCallMessage methodCall)
            {
                
    if (methodCall.InArgCount == 0)
                    
    return base.CreateReturnMessage(null, methodCall);

                
    string invokeid = GetInvokeMessageId(methodCall.MethodInfo);

                
    if (dict.ContainsKey(invokeid))
                    dict.Remove(invokeid);

                dict.Add(invokeid, methodCall.InArgs[
    0]);

                
    return base.CreateReturnMessage(null, methodCall);
            }

            
    private string GetInvokeMessageId(IDummyMethodInfo method)
            {
                StringBuilder builder 
    = new StringBuilder();
                builder.Append(method.Name.Substring(
    4));
                builder.Append(method.DeclaringType.FullName);
                
    //return builder.ToString();
                return Pixysoft.Security.MD5.GetMD5(builder.ToString());
            }
        }

        
    public interface IproxyWithProperty
        {
            
    string Name { set;get;}
        }

    测试代码如下: 

    代码
            //performance
            public void test002()
            {
                IproxyWithProperty pojo 
    = Pixysoft.Tools.PojoHelper.GetPojo<IproxyWithProperty>();

                IproxyWithProperty proxy 
    = new MyProxy<IproxyWithProperty>().Value;

                Pixysoft.Tools.CodeTimer.Initialize();

                Pixysoft.Tools.CodeTimer.Time(
    "pojo"100000delegate()
                {
                    pojo.Name 
    = "123";
                    
    object name = pojo.Name;
                });


                Pixysoft.Tools.CodeTimer.Time(
    "proxy"100000delegate()
                {
                    proxy.Name 
    = "123";
                    
    object name = proxy.Name;
                });
            }

    测试结果如下:

    ------ Test started: Assembly: Pixysoft.Framework.Reflection.dll ------


    pojo

    Time Elapsed: 7,997ms

    CPU time: 7,796,875,000ns

    Gen 0: 760

    Gen 1: 0

    Gen 2: 0


    proxy

    Time Elapsed: 5,651ms

    CPU time: 5,484,375,000ns

    Gen 0: 398

    Gen 1: 0

    Gen 2: 0



    1 passed, 0 failed, 0 skipped, took 13.77 seconds (Ad hoc).


    性能提高了1.415倍。

    如果把初始化proxy的代码放入循环,得到结果:

    ------ Test started: Assembly: Pixysoft.Framework.Reflection.dll ------


    pojo

    Time Elapsed: 8,569ms

    CPU time: 8,015,625,000ns

    Gen 0: 800

    Gen 1: 0

    Gen 2: 0


    proxy

    Time Elapsed: 6,263ms

    CPU time: 5,843,750,000ns

    Gen 0: 475

    Gen 1: 0

    Gen 2: 0


    性能提高了1.368倍。

    可以看出,微软的Realproxy本质上并不弱。 内部实现应该使用了类似emit的技术了。。。

    因此,一天的努力几乎有点白费了。。。竟然没有提高一个数量级。。。


    1 passed, 0 failed, 0 skipped, took 14.92 seconds (Ad hoc).


  • 相关阅读:
    Java 泛型 泛型的约束与局限性
    Java 泛型 泛型方法
    Java 泛型 泛型数组
    Java 泛型 协变性、逆变性
    Java 泛型 协变式覆盖和泛型重载
    Java 泛型 泛型代码和虚拟机
    Insertion Sort List
    Remove Duplicates from Sorted List II
    String to Integer (atoi)
    SpringMvc源码入门
  • 原文地址:https://www.cnblogs.com/zc22/p/1751974.html
Copyright © 2011-2022 走看看