Foreach vs list <t>. foreach

Source: Internet
Author: User

Today, when I use foreach loop to iterate a list <int>, I found that I became more familiar with performance problems, and I used to iterate an int arraylist, which I was a bit complacent. Benefiting from the benefits of generics, the C # compiler can use system. collections. generics. ienumerator <int> avoids a large number of boxing operations. collections. ienumerator. I started to think: Is this really the fastest way? After some research, this (foreach) is not the fastest way.

. NET 2.0 released some small nuggets, which makes it easier for us to write code. My favorite method is array and list <t>. Additional methods are added. These methods accept action <t>, converter <tinput, toutput> and predicate <t> are generic delegate. In fact, I am still fascinated by these things. The combination of these methods with anonymous methods and lambda expressions will play a significant role.

A special method of interest to me is list <t>. foreach (Action <t> ). I'm curious, is foreach calling faster or slower than a standard foreach-loop? Consider the following code:

 

[CSHARP]View plaincopyprint?
  1. Long sum (list <int> intlist)
  2. {
  3. Long result = 0;
  4. Foreach (int I in intlist)
  5. Result + = I;
  6. Return result;
  7. }

C # the compiler will generate pseudo code similar to the following for the above Code:

 

 

[CSHARP]View plaincopyprint?
  1. Long sum (list <int> intlist)
  2. {
  3. Long result = 0;
  4. List <t>. enumerator = intlist. getenumerator ();
  5. Try
  6. {
  7. While (enumerator. movenext ())
  8. {
  9. Int I = enumerator. Current;
  10. Result + = I;
  11. }
  12. }
  13. Finally
  14. {
  15. Enumerator. Dispose ();
  16. }
  17. Return result;
  18. }

In fact, the C # compiler generates two method calls for each iteration: ienumerator <t>. movenext () and ienumerator <t>. Current. List <t>. enumerator structure (implemented using ienumerator) allows the compiler to generateCallIl commands insteadCallvirtThis will improve performance a little. On the contrary, consider the following code:

 

 

[CSHARP]View plaincopyprint?
  1. Long sum (list <int> intlist)
  2. {
  3. Long result = 0;
  4. Intlist. foreach (delegate (int I) {result + = I ;});
  5. Result result;
  6. }

Or, the equivalent Lambda expression:

 

 

[CSHARP]View plaincopyprint?
  1. Long sum (list <int> intlist)
  2. {
  3. Long result = 0;
  4. Intlist. foreach (I => result + = I );
  5. Return result;
  6. }

Using list <t>. foreach only causes one method to be called in each iteration: No matter what action <t> delegate you provide. This will be called using the callvirt il command, but twoCallCommand (one movenext and one current) should be equal to oneCallvirtSlow command. So I expect that list <t>. foreach will be faster (than foreach ).

 

With these assumptions, I created a small console program, iterated A list <int> instance using different methods in the following 4, and summed up:

 

  1. Use for-loop iteration: For (INT I = 0; I <list <int>. Count; ++ I)
  2. Use for-loop, but do not call count: For (INT I = 0; I <num_items; ++ I)
  3. Use foreach-loop: foreach (int I in list <t>)
  4. Use List <int>. foreach for iteration: List <int>. foreach (delegate (int I) {result + = I ;})

 

First, optimization is not enabled in the test:


These results are unimaginable. Result: If Compiler optimization is not enabled, list <int>. foreach is faster than a for-loop! Foreach and for-loop are almost as fast. So if you compile your program without enabling optimization, list <int>. foreach is the fastest way.

Next, I turn on Compiler Optimization to get a more realistic result:

Looking at these numbers, the compiler is impressed with over 50% for-loop optimization. Foreach-loop also achieved an improvement of about 20%. List <int>. foreach does not get much optimization, but it should be noted that foreach is still much faster than foreach-loop.List <t>. foreach is faster than the standard foreach-loop..

Note that these tests run on a Dell think2's notebook with a CPU of Core Duo t2400 and 2 GB of memory. If you want to test some results by yourself, you can downloadForeachtest.zip (3.82kb ).

A picture is better than a thousand words. I generated a chart to show the speed difference between different iterations. The chart shows five different samples, from 10,000,000 to 50,000,000 iterations.

Compiler Optimization not started:

Enable Compiler Optimization:

Final point: although the foreach method is very fast in iterative list <t>, it is different when it comes to arrays. One-dimensional arrays do not have the foreach method, and foreach is much slower than foreach. The reason is that the compiler does not generate the ienumerator <t> code for the foreach iteration array. Using foreach to iterate the array, there is no way to call, but array. foreach will still call a delegate for each iteration (CallvirtCall ?).

Foreach vs list <t>. foreach

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.