Looping text with directional control The code is an implementation of looping text (similar to a circular buffer - wraps around when it reaches the edge of the defined bounds) with directional control.

The code is functional and works as intended, but I'm curious if there is anyway to improve the code even if it is only a small improvement (e.g. less garbage produced per loop cycle as a micro-optimisation, etc).

using System;
using System.Text;
using System.Threading;

namespace LoopingTextScroll
{
    internal class Program
    {
        private enum Direction
        {
            LeftToRight = -1,
            RightToLeft = 1
        }

        private static StringBuilder PadText(string text, int padding = 5)
        {
            var stringBuilder = new StringBuilder(text);
            stringBuilder.Append(new string(' ', padding));
            return stringBuilder;
        }

        private static void ShiftText(StringBuilder textBuilder, Direction direction)
        {
            var directionOffset = (int)direction;
            var textLength = textBuilder.Length;

            switch (direction)
            {
                case Direction.LeftToRight:
                {
                    for(var i = textLength - 1; i &gt;= 0; i--) textBuilder[i] = textBuilder[Modulo(i + directionOffset, textLength)];
                    break;
                }

                case Direction.RightToLeft:
                {
                    var firstElement = textBuilder[0];
                    for(var i = 0; i &lt; textLength; i++) textBuilder[i] = textBuilder[Modulo(i + directionOffset, textLength)];
                    textBuilder[textLength - 1] = firstElement;
                    break;
                }
            }
        }

        private static void UpdateLoop(string text, Direction direction = Direction.LeftToRight, int updateRate = 100)
        {
            var textBuilder = PadText(text);

            while (true)
            {
                ShiftText(textBuilder, direction);
                Console.Write($"\r{textBuilder}");
                Thread.Sleep(updateRate);
            }
        }

        private static int Modulo(int x, int m)
        {
            var remainder = x % m;
            return remainder &lt; 0 ? remainder + m : remainder;
        }

        public static void Main(string[] args)
        {
            UpdateLoop("Beautiful Lie", Direction.RightToLeft);
        }
    }
}
Your implementation can be greatly improved by using the System.Memory package. This will give you the new Memory&lt;char&gt; type (and if you're using .net-core it's already part of the SDK). With that you can create views of the string without creting any garbage.

At the same time you can make it more LINQ friendly. For this you can create the Slide extension that will return the slices of each part of the string and that accepts a Func for generating the offset for slicing. This one runs infinitely.

public static IEnumerable&lt;(Memory&lt;char&gt; X, Memory&lt;char&gt; Y)&gt; Slide(this string text, Func&lt;int, int&gt; calcOffset)
{
    var span = new Memory&lt;char&gt;(text.ToArray());
    while (true)
    {
        var offset = calcOffset(text.Length);
        var left = span.Slice(0, offset);
        var right = span.Slice(offset, text.Length - offset);
        yield return (right, left);
    }
}


You should also separate the logic for sliding and encapsulate each part in its own method. So you now have two of them.

public static Func&lt;int, int&gt; LeftToRight()
{
    var i = -1;
    return length =&gt;
    {
        i++;
        if (i &gt; length)
        {
            i = 0;
        }
        return i;
    };
}

public static Func&lt;int, int&gt; RightToLeft()
{
    var i = -1;
    return length =&gt;
    {
        i--;
        if (i &lt; 0)
        {
            i = length;
        }
        return i;
    };
}


To print it you can create another helper that encapsulates that part. Here you should replace the Thread.Sleep with Task.Delay which doesn't block/freeze the thread. With TimeSpan you can set the delay to whatever you want.

public static async Task PrintAsync(this IEnumerable&lt;(Memory&lt;char&gt; X, Memory&lt;char&gt; Y)&gt; source, TimeSpan delay)
{
    foreach (var element in source)
    {
        await Task.Delay(delay);
        Console.Clear();
        Console.Write(element.X);
        Console.WriteLine(element.Y);
    }
}




When you put everything together it'll look like that:

using  static Slider;

class Program
{
    static async Task Main(string[] args)
    {
        await
            "Hallo World"
                //.Slide(LeftToRight())
                .Slide(RightToLeft())
                .Take(20) // remove to run infinitely
                .PrintAsync(TimeSpan.FromMilliseconds(100));
    }
}


This is now garbage-free and does not create any additional sub-strings.