zoukankan      html  css  js  c++  java
  • C# Expression 表达式树 缓存

    在学习mvc3源代码的时候,发现里面调用action的源代码如下:

    private static ActionExecutor GetExecutor(MethodInfo methodInfo) {
                // Parameters to executor
                ParameterExpression controllerParameter = Expression.Parameter(typeof(ControllerBase), "controller");
                ParameterExpression parametersParameter = Expression.Parameter(typeof(object[]), "parameters");
    
                // Build parameter list
                List<Expression> parameters = new List<Expression>();
                ParameterInfo[] paramInfos = methodInfo.GetParameters();
                for (int i = 0; i < paramInfos.Length; i++) {
                    ParameterInfo paramInfo = paramInfos[i];
                    BinaryExpression valueObj = Expression.ArrayIndex(parametersParameter, Expression.Constant(i));
                    UnaryExpression valueCast = Expression.Convert(valueObj, paramInfo.ParameterType);
    
                    // valueCast is "(Ti) parameters[i]"
                    parameters.Add(valueCast);
                }
    
                // Call method
                UnaryExpression instanceCast = (!methodInfo.IsStatic) ? Expression.Convert(controllerParameter, methodInfo.ReflectedType) : null;
                MethodCallExpression methodCall = methodCall = Expression.Call(instanceCast, methodInfo, parameters);
    
                // methodCall is "((TController) controller) method((T0) parameters[0], (T1) parameters[1], ...)"
                // Create function
                if (methodCall.Type == typeof(void)) {
                    Expression<VoidActionExecutor> lambda = Expression.Lambda<VoidActionExecutor>(methodCall, controllerParameter, parametersParameter);
                    VoidActionExecutor voidExecutor = lambda.Compile();
                    return WrapVoidAction(voidExecutor);
                }
                else {
                    // must coerce methodCall to match ActionExecutor signature
                    UnaryExpression castMethodCall = Expression.Convert(methodCall, typeof(object));
                    Expression<ActionExecutor> lambda = Expression.Lambda<ActionExecutor>(castMethodCall, controllerParameter, parametersParameter);
                    return lambda.Compile();
                }
            }
    

    里面用了表达式树,当时的我对表达式树还不怎么了解,曾提出一个疑问,为什么不用反射而要用表达式树了,在网上找了很多资料说明表达式树比反射性能要高。甚至根由大牛曾提出表达式缓存的思想,http://blog.zhaojie.me/2009/03/expression-cache-2-simple-key-cache.html。然而在mvc3中有些地方还是用了表达式树缓存的(CachedExpressionCompiler mvc3自带的)

    至于怎么缓存我这里就不班门弄斧了,只是告诉一下大家Compile()这个东东很伤性能啊。

    现在说说我的测试吧:

    static void Main(string[] args)
            {
                TestExpress(100000);
                TestExpress(500000);
                Console.ReadLine();
            }
    
            private static void TestExpress(int count)
            {
                // int count = 100000;
                Console.WriteLine("循环次数:" + count);
                Expression<Func<int, int, int>> addExpr = (x, y) => x + y;
    
                var start = DateTime.Now;
                for (int i = 0; i < count; i++)
                {
                    Func<int, int, int> test = addExpr.Compile();
                    int result = test(1, 2);
                }
                var end = DateTime.Now;
                var time = end - start;
                Console.WriteLine("no Cache:" + time.Milliseconds);
                Func<int, int, int> addResult = addExpr.Compile();
                start = DateTime.Now;
                for (int i = 0; i < count; i++)
                {
                    int result = addResult(1, 2);
                }
                end = DateTime.Now;
                time = end - start;
                Console.WriteLine("Cache:" + time.Milliseconds);
            }
    

    我在release下得到的结果:


    在每个计算机每次执行的结果都是不同的,但是缓存了时间明显要短。

    我把有关Expression表达式树缓存 Expression表达式树序列化的源代码整理了一下,方便大家下载。http://download.csdn.net/detail/dz45693/4375232

  • 相关阅读:
    svn diff
    Design of a ProxySharing Proxy Server
    一个很好的多代理服务器调度软件-ProxyExpert(绿色软件) 『 软件使用交流 』 赢政天下 YingZheng.com Powered by Discuz!
    关于编译Qt以及驱动的一点总结吧 Rollen Holt 博客园
    Spring Bean Scope Prototype
    spring scope="prototype" 和scope="singleton"区分
    Struts2+hibernate+spring 配置文件中scope="prototype"的作用
    nginx 多级代理
    JS中的sleep
    《2013清明忆父》!
  • 原文地址:https://www.cnblogs.com/majiang/p/2564060.html
Copyright © 2011-2022 走看看