Lambda Master's Road Part II

Source: Internet
Author: User
Tags benchmark

Effects of http://www.cnblogs.com/lazycoding/archive/2013/01/06/2847579.html closures

To demonstrate the effects of closures, let's look at the following example.

var buttons = new button[ 10for (var i = 0; I < Buttons. Length; I++var button = new< Span style= "color: #000000;" > Button (); button. Text = (i + 1) +  " "; button. OnClick + = (s, e) => {MessageBox.Show (i.tostring ());}; Buttons[i] = button;} // What happens if we click the button       

This is a strange question, and I often ask my students in my JavaScript class. 95% of the students will say. Obviously button 0 shows 0, Button 1 shows 1, and so on. and less than 5% of the students learn the closure will understand. All the buttons will show 10.

The value of the local variable i has changed. and equals buttons. Length. That's 10. It's easy to avoid this weird situation. Here's the line.

New Button ();  var index =". Button-click for index! "; button. OnClick + = (s, e) = = {MessageBox.Show (index. ToString ()); };buttons[i] = button;      

The problem is resolved, but the index variable is a value type and therefore retains a copy of "global" I

The last topic is something called an expression tree, and he collaborates with lambda expressions. And he's going to make some amazing things happen to HTML extension methods in ASP. The key question is: How to find the target function

1. What is the name of the variable passed in?
2. What is the body of the method
3. What type is used in the function body

Expression solves these problems by allowing us to dig into the generated expression tree, and we can also execute functions passed to the Func and action delegates, and the lambda expression can be resolved at run-time

Let's take a look at examples of how to use expression types

Int>> expr = model + model. MyProperty; as memberexpression;  when member! = NULL is executed ...    

This is the simplest use of expression. The rules are fairly straightforward. By building an object of type expression. The compiler generates some metadata for the generated interpretation tree. This interpretation tree contains all relevant information, such as parameters and method bodies.

The method body contains the complete interpretation tree, and we can access these operations. Just like the complete statement. You can also manipulate the return reference and type. Of course, the return can be null, either way. Most of the cases. We are interested in expressions. This is very similar to the method of working with expression types in ASP.-You can get the names of the parameters used, and the benefits are obvious. There is no spelling error in the name. There will be no compilation errors that occur.

Note: When the programmer is only interested in the name of the property being called. There is a simpler, more elegant solution, that is, the parameter attribute callermembername this feature to get the name of the calling method/property. Fields are automatically populated by the compiler. So if we just want to know the name and don't want to know more about it, then I just need to write the code like the one in the example below. The name of the method can be returned by calling the Whatsmyname () method

Null) {    return callingname;}  

Performance of lambda expressions

There is a big question: how fast is the lambda expression? All right. First, we expect them to be as fast as our normal functions. In the next section. We will see that the MSIL code of lambda is not much different from the normal function.

One of the most interesting discussions is that if a lambda expression produces a closure, it will be as fast as a method that uses global variables. This creates an interesting question, and how much does it matter how many local variables are in a region?

Let's look at the test code, and with 4 different indicators, we can see the difference between the normal method and the lambda method.

UsingSystem;UsingSystem.Collections.Generic;UsingSystem.Diagnostics;Namespacelambdatests{ClassStandardbenchmark:benchmark {Constint LENGTH =100000;StaticDouble[] A;StaticDouble[] B;StaticvoidInit () {var r =NewRandom (); A =NewDouble[LENGTH]; B =NewDouble[LENGTH];for (var i =0; i < LENGTH; i++) {A[i] =R.nextdouble (); B[i] =R.nextdouble (); } }StaticLongLambdabenchmark () {func<Double> Perform = () ={var sum =0.0;for (var i =0; i < LENGTH; i++) sum + = a[i] *B[i];ReturnSum };var iterations =Newdouble[100];var timing =NewStopwatch (); Timing. Start ();for (var j =0; J < Iterations. Length; J + +) Iterations[j] =Perform (); Timing. Stop (); Console.WriteLine ("Time for Lambda-benchmark: \ t {0}ms", timing. Elapsedmilliseconds);ReturnTiming. Elapsedmilliseconds; }StaticLongNormalbenchmark () {var iterations =Newdouble[100];var timing =NewStopwatch (); Timing. Start ();for (var j =0; J < Iterations. Length; J + +) Iterations[j] =Normalperform (); Timing. Stop (); Console.WriteLine ("Timefor Normal-benchmark: \ t {0}ms", timing. Elapsedmilliseconds); return timing. Elapsedmilliseconds; } static double Normalperform () { var sum = 0.0; For (var i = 0; i < LENGTH; i++) sum + = a[i] * b[i]; return sum;                 }}} 

We could write the code better by using lambda expressions. I didn't do it in the end. is to prevent the effects from seeing the final result. So, essentially. There are three methods in the code above
One is a lambda test, one is a normal test, and the other is a method called in a normal test. The fourth method that we don't have is actually our lambda expression. has been created in the first method. The calculation process is simple, and we randomly take the numbers to prevent the compiler from doing any optimizations. Finally, we are interested in the difference between common methods and lambda methods.

If we run this test program. We will find that lambda expressions are not always worse than normal methods. What surprises us is that sometimes even lambda expressions are faster. However, in the case of closures, it is wrong. This means that in most cases we can use lambda expressions without hesitation. There is a little bit of performance loss when using closures, but fortunately, the next section tells you a few reasons for performance loss.
Here is the result table for the test output

Test Lambda [MS] Normal [MS]
0 45+-1 46+-1
1 44+-1 46+-2
2 49+-3 45+-2
3 48+-2 45+-2

As a result of the above table, we can see that the normal method and the lambda expression basically limit the same. There is no significant performance penalty when using lambda expressions.

Lambda Master's Road Part II

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.