当不使用拉姆达EX pressions [英] When not to use lambda expressions

查看:177
本文介绍了当不使用拉姆达EX pressions的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个很大的问题正在回答了堆叠式和NBSP;溢水口,成员指定如何使用拉姆达前解决这些现实世界/时间问题pressions 的。

A lot of questions are being answered on Stack Overflow, with members specifying how to solve these real world/time problems using lambda expressions.

我们是否过度使用它,并且我们考虑使用lambda EX pressions对性能的影响?

Are we overusing it, and are we considering the performance impact of using lambda expressions?

我找到了几篇文章,探讨拉姆达VS匿名委托VS / 的foreach 的性能影响循环使用不同的结果。

I found a few articles that explores the performance impact of lambda vs anonymous delegates vs for/foreach loops with different results

  1. <一个href="http://blogs.microsoft.co.il/blogs/alex_golesh/archive/2007/12/11/anonymous-delegates-vs-lambda-ex$p$pssions-vs-function-calls-performance.aspx">Anonymous与会代表VS LAMBDA防爆pressions VS函数调用性能
  2. 性能的foreach与List.ForEach
  3. .NET / C#循环性能测试(FOR,FOREACH,LINQ ,&安培; LAMBDA)
  4. <一个href="http://stackoverflow.com/questions/626679/datatable-select-vs-datatable-rows-find-vs-foreach-vs-find$p$pdicatet-lambda/650922#650922">DataTable.Select比LINQ
  5. 更快
  1. Anonymous Delegates vs Lambda Expressions vs Function Calls Performance
  2. Performance of foreach vs. List.ForEach
  3. .NET/C# Loop Performance Test (FOR, FOREACH, LINQ, & Lambda).
  4. DataTable.Select is faster than LINQ

在选择合适的解决方案应该是什么评价标准?除了显而易见的原因,它更简洁code和可读性使用lambda的时候。

What should be the evaluation criteria when choosing the appropriate solution? Except for the obvious reason that it's more concise code and readable when using lambda.

推荐答案

尽管我将集中在一点一点,我首先给我的2美分的业绩整体问题。除非差异大或使用密集,通常我不会理会微秒时添加不构成任何明显的差异给用户。我强调的是,我只考虑非密集型调用的方法时,也就无所谓了。我在那里做有特殊性能的考虑是我设计的应用程序本身的方式。我关心缓存,关于使用线程,约聪明的方法来调用方法(是否要进行多次电话或设法使只有一个呼叫),是否要缓存连接与否,等等,等等。其实我平时不要T专注于原始性能,但scalibility。如果它运行由一纳秒为单个用户的一小片更好,我不在乎,但我在乎了很多有加载系统的并发用户数量大不知不觉的影响的能力。

Even though I will focus on point one, I begin by giving my 2 cents on the whole issue of performance. Unless differences are big or usage is intensive, usually I don't bother about microseconds that when added don't amount to any visible difference to the user. I emphasize that I only don't care when considering non-intensive called methods. Where I do have special performance considerations is on the way I design the application itself. I care about caching, about the use of threads, about clever ways to call methods (whether to make several calls or to try to make only one call), whether to pool connections or not, etc., etc. In fact I usually don't focus on raw performance, but on scalibility. I don't care if it runs better by a tiny slice of a nanosecond for a single user, but I care a lot to have the ability to load the system with big amounts of simultaneous users without noticing the impact.

说了这么多,在这里不用我约点1.我喜欢匿名方法的意见。他们给了我很大的灵活性和code优雅。有关匿名的方法的另一很大的特点是,它们允许(当然从C#的角度来看,不从将IL的角度来看,)我直接从容器的方法使用局部变量。他们饶了我的code加载经常。什么时候使用匿名方法?埃维单一时间未在其他地方所需要的那块code,我需要。如果它被用在两个不同的地方,我不喜欢复制粘贴作为复用技术,所以我会用纯醇'的代表。所以,就像shoosh回答,这不是件好事,code重复。从理论上讲,没有性能上的差异为化名是C#中的技巧,而不是IL的东西。

Having said that, here goes my opinion about point 1. I love anonymous methods. They give me great flexibility and code elegance. The other great feature about anonymous methods is that they allow me to directly use local variables from the container method (from a C# perspective, not from an IL perspective, of course). They spare me loads of code oftentimes. When do I use anonymous methods? Evey single time the piece of code I need isn't needed elsewhere. If it is used in two different places, I don't like copy-paste as a reuse technique, so I'll use a plain ol' delegate. So, just like shoosh answered, it isn't good to have code duplication. In theory there are no performance differences as anonyms are C# tricks, not IL stuff.

的大部分事情我想匿名方法适用于拉姆达EX pressions,因为后者可以作为一种简洁的语法重新present匿名方法。让我们假定以下方法:

Most of what I think about anonymous methods applies to lambda expressions, as the latter can be used as a compact syntax to represent anonymous methods. Let's assume the following method:

    public static void DoSomethingMethod(string[] names, Func<string, bool> myExpression)
    {
        Console.WriteLine("Lambda used to represent an anonymous method");
        foreach (var item in names)
        {
            if (myExpression(item))
                Console.WriteLine("Found {0}", item);
        }
    }

它接收字符串数组并为他们每个人,它会调用传递给它的方法。如果该方法返回true,它会说找到了......。您可以调用此方法通过以下方式:

It receives an array of strings and for each one of them, it will call the method passed to it. If that method returns true, it will say "Found...". You can call this method the following way:

        string[] names = {"Alice", "Bob", "Charles"};
        DoSomethingMethod(names, delegate(string p) { return p == "Alice"; });

不过,你也可以把它通过以下方式:

But, you can also call it the following way:

        DoSomethingMethod(names, p => p == "Alice");

有一个在IL两者之间没有什么区别,在于一个使用LAMBDA EX pression是更具可读性。再次,没有性能影响,因为这些都是C#编译器的技巧(没有JIT编译器的技巧)。正如我不觉得我们是过度使用匿名方法,我不觉得我们是过度使用LAMBDA EX pressions重新present匿名方法。当然,同样的逻辑也适用于反复code:不要做lambda表达式,使用常规的代表。还有其他的限制,导致用户返回到匿名方法或普通的代表,像传出或引用参数传递。

There is no difference in IL between the both, being that the one using the Lambda expression is much more readable. Once again, there is no performance impact as these are all C# compiler tricks (not JIT compiler tricks). Just as I didn't feel we are overusing anonymous methods, I don't feel we are overusing Lambda expressions to represent anonymous methods. Of course, the same logic applies to repeated code: Don't do lambdas, use regular delegates. There are other restrictions leading you back to anonymous methods or plain delegates, like out or ref argument passing.

有关LAMBDA EX pressions另一个好东西是完全一样的语法并不需要再present匿名方法。 LAMBDA EX pressions也可以重新present ......你猜,EX pressions。看看下面的例子:

The other nice things about Lambda expressions is that the exact same syntax doesn't need to represent an anonymous method. Lambda expressions can also represent... you guessed, expressions. Take the following example:

    public static void DoSomethingExpression(string[] names, System.Linq.Expressions.Expression<Func<string, bool>> myExpression)
    {
        Console.WriteLine("Lambda used to represent an expression");
        BinaryExpression bExpr = myExpression.Body as BinaryExpression;
        if (bExpr == null)
            return;
        Console.WriteLine("It is a binary expression");
        Console.WriteLine("The node type is {0}", bExpr.NodeType.ToString());
        Console.WriteLine("The left side is {0}", bExpr.Left.NodeType.ToString());
        Console.WriteLine("The right side is {0}", bExpr.Right.NodeType.ToString());
        if (bExpr.Right.NodeType == ExpressionType.Constant)
        {
            ConstantExpression right = (ConstantExpression)bExpr.Right;
            Console.WriteLine("The value of the right side is {0}", right.Value.ToString());
        }
     }

请注意,稍有不同的签名。第二个参数接收前pression而不是委托。调用此方法的方法是:

Notice the slightly different signature. The second parameter receives an expression and not a delegate. The way to call this method would be:

    DoSomethingExpression(names, p => p == "Alice");

这是完全一样创建一个匿名方法的lambda的时候,我们打了电话。这里的区别是,我们没有创建一个匿名方法,但在创建前pression树。也正是由于这些前pression树,我们可以再转换成拉姆达EX pressions到SQL,这正是LINQ的2 SQL做的,而不是在发动机执行的东西,对于像其中的每个条款,例如,选择等的好处是,调用语法是一样的,不管你在创建一个匿名方法或发送前pression。

Which is exactly the same as the call we made when creating an anonymous method with a lambda. The difference here is that we are not creating an anonymous method, but creating an expression tree. It is due to these expression trees that we can then translate lambda expressions to SQL, which is what Linq 2 SQL does, for instance, instead of executing stuff in the engine for each clause like the Where, the Select, etc. The nice thing is that the calling syntax is the same whether you're creating an anonymous method or sending an expression.

这篇关于当不使用拉姆达EX pressions的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆