Day 26 of 30-Day .NET Challenge: Loop Unrolling

Day 26 of 30-Day .NET Challenge: Loop Unrolling

Learn to enhance your loop performance in C#. Discover a better approach using Loop Unrolling on Day 26 of our 30-Day .NET Challenge.


Introduction

The article demonstrates the advantages of loop unrolling by iterating over multiple items per cycle while adjusting the loop counter accordingly.

Learning Objectives

  • The problem with iterating using traditional loops

  • Advantages with loop unrolling

Prerequisites for Developers

  • Basic understanding of C# programming language.

  • Familiar with for loops

30 Day .Net Challenge

Getting Started

The problem with iterating using traditional loops

Most developers will iterate over array elements and perform a mathematical operation as shown in the following code snippet.

for (int i = 0; i < array.Length; i++)
{
    array[i] = i * 2;
}

Although the above code snippet is quite clean and straightforward, it incurs a cost due to the loop control structure.

Advantages with loop unrolling

Please find below the refactored version of the previous code snippet

int len = array.Length;
for (int i = 0; i < len; i += 4)
{
    array[i] = i * 2;
    if (i + 1 < len) array[i + 1] = (i + 1) * 2;
    if (i + 2 < len) array[i + 2] = (i + 2) * 2;
    if (i + 3 < len) array[i + 3] = (i + 3) * 2;
}

With refactored code, now we have reduced the loop frequency to 4 which leads to faster execution.

In addition to that, it will reduce

  • Reduce loop overheads which in turn decreases any conditional checks inside the loops.

  • Increase performance as it enhances the execution speed

Complete Code

Create another class named LoopUnrolling and add the following code snippet


public static class LoopUnrolling
{
    public static void BadWay() {
        const int size = 1024;
        int[] numbers = new int[size];

        // Traditional loop
        var watch = System.Diagnostics.Stopwatch.StartNew();
        for (int i = 0; i < numbers.Length; i++)
        {
            numbers[i] = i * 2;
        }
        watch.Stop();
        Console.WriteLine($"Traditional loop time: {watch.ElapsedTicks} ticks");

    }
    public static void GoodWay()
    {
        const int size = 1024;
        int[] numbers = new int[size];
        int len = numbers.Length;
        var watch = System.Diagnostics.Stopwatch.StartNew();
        for (int i = 0; i < len; i += 4)
        {
            numbers[i] = i * 2;
            if (i + 1 < len) numbers[i + 1] = (i + 1) * 2;
            if (i + 2 < len) numbers[i + 2] = (i + 2) * 2;
            if (i + 3 < len) numbers[i + 3] = (i + 3) * 2;
        }
        watch.Stop();
        Console.WriteLine($"Unrolled loop time: {watch.ElapsedTicks} ticks");
    }
}

Execute from the main method as follows

#region Day 26: Loop Unrolling
static string ExecuteDay26()
{
    LoopUnrolling.BadWay();
    LoopUnrolling.GoodWay();

    return "Executed Day 26 successfully..!!";
}

#endregion

Console Output

Traditional loop time: 20 ticks
Unrolled loop time: 12 ticks

As the output demonstrates loop unrolling took much less time than the traditional loop approach.

Complete Code on GitHub

GitHub — ssukhpinder/30DayChallenge.Net


C# Programming🚀

Thank you for being a part of the C# community! Before you leave:

Follow us: Youtube | X | LinkedIn | Dev.to
Visit our other platforms: GitHub
More content at C# Programming

Did you find this article valuable?

Support Sukhpinder Singh by becoming a sponsor. Any amount is appreciated!