If you do not use lambda expressions

A lot of questions will be answered on Qaru, in which participants indicate how to solve these real-world / time problems using lambda expressions .

Do we use this overuse and consider the effect of performance on the use of lambda expressions?

I found several articles that examined the impact of lambda vs anonymous delegates vs for / foreach performance on different results

What should be the evaluation criteria when choosing the right solution? Except for the obvious reason that it is more concise code and reads when using lambda.

+50
c # lambda anonymous-methods
Mar 23 '09 at 10:49
source share
9 answers

Despite the fact that I will focus on the first point, I start by giving 2 cents for the entire production output. If the differences are not significant or the intensity of use, I usually do not worry about microseconds, which when added do not represent any visible difference to the user. I emphasize that I don't care if we consider non-intensive callable methods. Where I have specific performance considerations, I develop the application myself. I care about caching, about using threads, about smart ways to call methods (make multiple calls or try to make only one call), whether to connect connections or not, etc. Etc. In fact, I usually focus on raw performance, but on scalability. I don't care if it works better for a tiny bit of a nanosecond for a single user, but I really like being able to boot the system with a lot of concurrent users without noticing the impact.

Having said that, here is my opinion on paragraph 1. I love anonymous methods. They give me great flexibility and code elegance. Another great feature of anonymous methods is that they allow me to directly use local variables from the container method (from the point of view of C #, and not from the point of view of IL, of course). They save me from downloading code. When do I use anonymous methods? Evey at a time, the part of the code that I need is not needed elsewhere. If it is used in two different places, I don't like copy-paste as a reuse method, so I use a simple delegate. So, as Shoosh replied, it's nice to have code duplication. In theory, there are no differences in performance, since anonyms are C # tricks, not IL things.

Most of what I think of anonymous methods relates to lambda expressions, since the latter can be used as compact syntax for representing anonymous methods. Take 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); } } 

He receives an array of strings and for each of them, he will call the method passed to him. If this method returns true, it will say "Found ...". You can call this method as follows:

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

But you can also call it like this:

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

In IL, there is no difference between the one who uses the Lambda expression is much readable. Once again, the performance impact is not affected, since all these are C # compiler tricks (and not JIT compiler tricks). Just as I did not feel that we were abusing anonymous methods, I did not feel that we were abusing lambda expressions to represent anonymous methods. Of course, the same logic applies to re-code: don't do lambda, use persistent delegates. There are other restrictions that lead you to anonymous methods or simple delegates, such as out or ref argument.

Another nice thing about Lambda expressions is that the same syntax should not represent an anonymous method. Lambda expressions can also represent ... you guessed it, 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()); } } 

Pay attention to a slightly different signature. The second parameter receives the expression, not the delegate. The way to call this method:

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

This is exactly the same as the call that we created when creating the anonymous method using lambda. The difference here is that we are not creating an anonymous method, but creating an expression tree. It is because of these expression trees that we can then translate lambda expressions into SQL, which, for example, does Linq 2 SQL, instead of launching material in the engine for each sentence, such as Where, Select, etc. The good thing is that the call syntax is the same regardless of whether you create an anonymous method or send an expression.

+31
Mar 23 '09 at 12:27
source share

My answer will not be popular.

I believe Lambda is 99% always the best choice for three reasons.

Firstly, there’s absolutely nothing wrong with assuming your developers are smart. Other answers have a fundamental premise that every developer, but you are stupid. Not this way.

Secondly, Lamdas (and others) are modern syntax - and tomorrow they will become more common than they are today. The project code should flow from current and emerging agreements.

Third, writing the "old fashioned way" code may seem easier for you, but it’s not so easy for the compiler. This is important; legacy approaches have little room for improvement as the compiler updates. Lambdas (and others), who rely on the compiler to extend them, may benefit, since the compiler handles them better over time.

Summarizing:

  • Developers can handle this.
  • Everybody do it
  • There future potential

Again, I know this will not be a popular answer. And believe me, "Simple is the best" is also my mantra. Maintenance is an important aspect for any source. I understood. But I think that we obscure reality with some rules of thumb.

//Jerry

+23
Dec 20 '11 at 10:27
source share

Code duplication.
If you find yourself using the same anonymous function multiple times, it should not be like that.

+15
Mar 23 '09 at 10:56
source share

Well, when we talk about delegate delegation, there should not be any difference between lambdas and anonymous methods - they are the same, but with different syntax. Named methods (used as delegates) are also identical in terms of runtime. So the difference is in using delegates as well as inline code - i.e.

 list.ForEach(s=>s.Foo()); // vs. foreach(var s in list) { s.Foo(); } 

(where I would expect the latter to be faster)

And equally, if you are talking about anything other than objects in memory, lambdas is one of your most powerful tools for maintaining type checking (and not for parsing strings).

Of course, there are times when a simple foreach with code will be faster than the LINQ version, since there will be fewer calls, and it will cost a small but measurable time. However, in many cases, the code is simply not a bottleneck, and a simpler code (especially for grouping, etc.) costs much more than a few nanoseconds.

Note that in .NET 4.0 there are additional Expression nodes for things like loops, commas, etc. Language do not support them, but runtime. I mention this only for completeness: I certainly do not say that you should use the Expression construct to guide where foreach will do!

+14
Mar 23 '09 at 11:13
source share

I would say that the differences in performance are usually so small (and in the case of loops, obviously if you look at the results of the second article (by the way, Jon Skeet has a similar article here )) that you almost never choose a solution just for performance reasons unless you write a piece of software where performance is absolutely number one non-functional requirement and you really need to do micro-optimizations.

When to choose what? I think it depends on the situation, but also on the person. As an example, some people forward List.Foreach through a regular foreach loop. I personally prefer the latter, as it is usually more readable, but who am I to object to this?

+6
Mar 23 '09 at 11:14
source share

Thumb rules:

  • Write your code as natural and readable.
  • Avoid code duplication (lambda expressions may require a little extra zeal).
  • Optimize only when there is a problem, and only with data, to back up this problem.
+4
Mar 23 '09 at 11:28
source share

Whenever a lambda simply passes its arguments directly to another function. Do not create a lambda application for functions.

Example:

 var coll = new ObservableCollection<int>(); myInts.ForEach(x => coll.Add(x)) 

Better than:

 var coll = new ObservableCollection<int>(); myInts.ForEach(coll.Add) 

The main exception is that C # type inference is not possible for any reason (and there are many times that it is true).

+4
Mar 23 '09 at 17:57
source share

If you need recursion, do not use lambdas, or you will get very distracted !

+2
Mar 23 '09 at 11:35
source share

Lambda expressions are cool. In the older delegate syntax , they have several advantages, such as: they can be converted to an anonymous function or expression trees, parameter types are derived from the declaration, they are cleaner and more concise, etc. I don't see the real meaning, not to use a lambda expression when you need an anonymous function. One not-so-big advantage than before is that you can completely omit the parameter declaration if they are not used. how

 Action<int> a = delegate { }; //takes one argument, but no argument specified 

This is useful when you need to declare an empty delegate that does nothing, but that is not a good reason not to use lambdas.

Lambdas allows you to write fast anonymous methods. Now this makes lambdas meaningless wherever anonymous methods become meaningless, i.e. When the named methods make more sense. According to the mentioned methods, anonymous methods can be disadvantageous (and not lambda expressions as such, but since lambdas today are widely anonymous methods, this is true):

  • because it tends to lead to duplication of logic (often this is difficult, reuse)

  • when there is no need to write in one, for example:

     //this is unnecessary Func<string, int> f = x => int.Parse(x); //this is enough Func<string, int> f = int.Parse; 
  • since writing an anonymous iterator block is not possible.

     Func<IEnumerable<int>> f = () => { yield return 0; }; //impossible 
  • as recursive lambdas need another line of quirkiness like

     Func<int, int> f = null; f = x => (x <= 1) ? 1 : x * f(x - 1); 
  • well, since reflection is a kind of Messier, but this is a moot point, is not it?

Besides point 3, the rest are not good reasons not to use lambda.

Also see this thread on what is not beneficial for Func/Action delegates, as they are often used with lambda expressions.

+2
Dec 20 '13 at 12:51
source share



All Articles