• 自制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).


  • 相关阅读:
    为什么硬链接不能链接目录、文件inode 和目录 dentry 的区别联系
    LVM 详解
    pwd 命令详解
    type 命令详解
    查看文件中字符出现次数
    lesson
    xml linq
    新系统配置
    空合并运算符(??):
    dos.ORM配置和使用
  • 原文地址:https://www.cnblogs.com/zc22/p/1751974.html
Copyright © 2020-2023  润新知