برچسب: Loop

  • how to get the index of an item in a foreach loop | Code4IT


    Do you need the index of the current item in a foreach loop with C#? Here you’ll see two approaches.

    Table of Contents

    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    Sometimes, when looping over a collection of elements in C#, you need not only the items itself, but also its position in the collection.

    How to get the index of the current element in a foreach loop?

    The easiest way is to store and update the index in a separate variable

    List<string> myFriends = new List<string> {
        "Emma", "Rupert", "Daniel", "Maggie", "Alan"
    };
    
    int index = 0;
    foreach (var friend in myFriends)
    {
        Console.WriteLine($"Friend {index}: {friend}");
        index++;
    }
    

    This works fine, nothing to add.

    But, if you want something a little more elegant and compact, you can use the Select method from LINQ:

    List<string> myFriends = new List<string> {
      "Emma", "Rupert", "Daniel", "Maggie", "Alan"
    };
    
    foreach (var friend in myFriends.Select((name, index) => (name, index)))
    {
      Console.WriteLine($"Friend {friend.index}: {friend.name}");
    }
    

    Why do I like this solution?

    • it’s more compact than the first one
    • there is a tight bond between the current item in the loop and the index
    • I find it cleaner and easier to read

    Or… You can just replace it with a simple for loop!

    What about performance?

    I’ve done a simple benchmark (see here), and it resulted that for lists with less than 1000 items, the first solution is faster, and for lists with 10000 items, using LINQ is way faster than using an external index.

    Size (#items) With simple index (ms) With LINQ (ms)
    100 96 128
    1000 1225 1017
    10000 5523 786

    This happens with .NET 5.

    Update 2021-06-09: the previous benchmark was wrong!!😐

    The times listed in the previous table were misleading: I calculated those durations using a StopWatch and calling it in different methods.

    But, when performing a more precise benchmark using Benchmark.NET, the results are totally different.

    With .NET Core 3.1.14 I get the following results:

    Method array Mean Error
    WithIndex Int32[10000] 269,386.4 ns 6,168.76 ns
    WithLinq Int32[10000] 396,421.3 ns 7,778.64 ns
    WithIndex Int32[1000] 25,438.3 ns 504.03 ns
    WithLinq Int32[1000] 39,981.3 ns 1,578.48 ns
    WithIndex Int32[100] 2,440.8 ns 48.34 ns
    WithLinq Int32[100] 3,687.7 ns 73.60 ns
    WithIndex Int32[10] 185.6 ns 3.52 ns
    WithLinq Int32[10] 369.5 ns 9.51 ns

    While with .NET 5 I get these results:

    Method array Mean Error
    WithIndex Int32[10000] 134,431.02 ns 2,181.244 ns
    WithLinq Int32[10000] 273,691.68 ns 5,334.833 ns
    WithIndex Int32[1000] 12,961.69 ns 233.351 ns
    WithLinq Int32[1000] 26,023.63 ns 495.341 ns
    WithIndex Int32[100] 1,088.25 ns 21.485 ns
    WithLinq Int32[100] 2,299.12 ns 21.901 ns
    WithIndex Int32[10] 48.01 ns 0.748 ns
    WithLinq Int32[10] 228.66 ns 4.531 ns

    As you can see, actually using LINQ is slower than using a simple index. While in .NET Core 3 the results were quite similar, with .NET 5 there was a huge improvement both cases, but now using a simple index is two times faster than using LINQ.

    SORRY FOR THAT MISLEADING INFO! Thank you, Ben, for pointing it out in the comments section! 🙏

    Below you can see the code I used for this benchmark. I you want to get started with Benchmark.NET, look at the documentation or to my article Enum.HasFlag performance with BenchmarkDotNet

    public class ForeachIndexBenchmark
      {
          public IEnumerable<int[]> Arrays()
          {
              yield return Enumerable.Range(0, 10).ToArray();
              yield return Enumerable.Range(0, 100).ToArray();
              yield return Enumerable.Range(0, 1000).ToArray();
              yield return Enumerable.Range(0, 10000).ToArray();
          }
    
          [Benchmark]
          [ArgumentsSource(nameof(Arrays))]
          public void WithIndex(int[] array)
          {
              int index = 0;
              var asString = "0";
              foreach (var friend in array)
              {
                  asString = "" + index;
                  index++;
              }
          }
    
          [Benchmark]
          [ArgumentsSource(nameof(Arrays))]
          public void WithLinq(int[] array)
          {
              var asString = "0";
    
              foreach (var friend in array.Select((item, index) => (item, index)))
              {
                  asString = "" + friend.index;
              }
          }
      }
    

    This article first appeared on Code4IT

    Conclusions

    We’ve discovered that there are many ways to use indexes tightly bound with items. If you look at performance, go for the simplest ways (for loop or foreach with simple index). If you want a more concise code, go for LINQ.

    Anything else to add?

    👉 Let’s discuss it on Twitter or on the comment section below!

    🐧





    Source link

  • Raise synchronous events using Timer (and not a While loop) &vert; Code4IT

    Raise synchronous events using Timer (and not a While loop) | Code4IT


    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    There may be times when you need to process a specific task on a timely basis, such as polling an endpoint to look for updates or refreshing a Refresh Token.

    If you need infinite processing, you can pick two roads: the obvious one or the better one.

    For instance, you can use an infinite loop and put a Sleep command to delay the execution of the next task:

    while(true)
    {
        Thread.Sleep(2000);
        Console.WriteLine("Hello, Davide!");
    }
    

    There’s nothing wrong with it – but we can do better.

    Introducing System.Timers.Timer

    The System.Timers namespace exposes a cool object that you can use to achieve that result: Timer.

    You then define the timer, choose which event(s) must be processed, and then run it:

    void Main()
    {
        System.Timers.Timer timer = new System.Timers.Timer(2000);
        timer.Elapsed += AlertMe;
        timer.Elapsed += AlertMe2;
    
        timer.Start();
    }
    
    void AlertMe(object sender, ElapsedEventArgs e)
    {
        Console.WriteLine("Ciao Davide!");
    }
    
    void AlertMe2(object sender, ElapsedEventArgs e)
    {
        Console.WriteLine("Hello Davide!");
    }
    

    The constructor accepts in input an interval (a double value that represents the milliseconds for the interval), whose default value is 100.

    This class implements IDisposable: if you’re using it as a dependency of another component that must be Disposed, don’t forget to call Dispose on that Timer.

    Note: use this only for synchronous tasks: there are other kinds of Timers that you can use for asynchronous operations, such as PeriodicTimer, which also can be stopped by canceling a CancellationToken.

    This article first appeared on Code4IT 🐧

    Happy coding!

    🐧



    Source link

  • 4 Python Loop Mistakes Everyone Makes (And How to Fix Them)



    4 Python Loop Mistakes Everyone Makes (And How to Fix Them)



    Source link