Привет, любители производительности, пришло время оптимизировать ваш код и получить более быстрое приложение дикого дикого запада.

Эта статья поможет вам расширить свои знания о производительности, чтобы вы могли создать историю в своем бэклоге с названием «Повысить производительность в службе XXX» и совершить свое ВОЛШЕБСТВО и сократить не только память, но и эти драгоценные золотые миллисекунды. на ответ ваших конечных точек от вашего приложения.

Уменьшение объема памяти и времени означает сокращение затрат на инфраструктуру, что делает всех менеджеров счастливыми.

ОХВАТЫВАТЬ

Встречаем Span!

Итак, что такое Span?

«О, я знаю, я знаю!!! Это HTML-тег, используемый для формулировки контента на FrontEnd!».

Span‹› – это представление смежных областей произвольной памяти без распределения.

Красиво, а что это значит на человеческом языке? БЕСПЛАТНОЕ РАЗМЕЩЕНИЕ!!!

Это означает, что использование Span не будет выделять память и отправит сборщик мусора в отпуск на несколько дней.

Давайте попробуем и посмотрим, работает ли это.

Например, в вашем приложении вам приходится иметь дело с логикой, которая использует SubString для управления позициями строк.

Что-то вроде этого:

namespace Span
{
    class Program
    {
        private static readonly string someString = "01 02 03";

        static void Main(string[] args)
        {
            var numbers = ExtractNumbers();
            Console.WriteLine(numbers);
        }

        public static (int pos1, int pos2, int pos3) ExtractNumbers()
        {
            var strNumber1 = someString.Substring(0, 2);
            var strNumber2 = someString.Substring(2, 4);
            var strNumber3 = someString.Substring(6);

            return (int.Parse(strNumber1), int.Parse(strNumber2), int.Parse(strNumber3));

        }
    }
}

Итак, у нас есть извлечение чисел из строки, а затем запись в консоль, и результат равен этому:

Хорошо, теперь давайте попробуем новый подход Span с той же логикой и посмотрим на результаты.

namespace Span
{
    class Program
    {
        private static readonly string someString = "01 02 03";

        static void Main(string[] args)
        {
            var numbers = ExtractNumbersWithSpan();
            Console.WriteLine(numbers);
        }

        public static (int pos1, int pos2, int pos3) ExtractNumbersWithSpan()
        {
            ReadOnlySpan<char> spanString = someString;
            var strNumber1 = spanString.Slice(0, 2);
            var strNumber2 = spanString.Slice(2, 4);
            var strNumber3 = spanString.Slice(6);

            return (int.Parse(strNumber1), int.Parse(strNumber2), int.Parse(strNumber3));
        }
    }
}

Используя Span и изменив «SubString» на «Slice», мы получим тот же результат:

Довольно просто, верно?

Да, хорошо, но насколько это более продуктивно, чем «Подстрока»??

Давайте проверим, НАСТАЛО ВРЕМЯ ДЛЯ ЭТАЛОНА!!!

Сначала установите BenchmarkDotNet и не забудьте перевести свое решение в режим выпуска, чтобы запустить BenchMark.

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

namespace Span
{
    class Program
    {
        static void Main(string[] args)
        {
            BenchmarkRunner.Run<Bench>();
        }
    }


        [MemoryDiagnoser]
        public class Bench
        {
            public static readonly string someString = "01 02 03";

            [Benchmark]
            public (int pos1, int pos2, int pos3) ExtractNumbers()
            {
                var strNumber1 = someString.Substring(0, 2);
                var strNumber2 = someString.Substring(2, 4);
                var strNumber3 = someString.Substring(6);

                return (int.Parse(strNumber1), int.Parse(strNumber2), int.Parse(strNumber3));
            }

            [Benchmark]
            public (int pos1, int pos2, int pos3) ExtractNumbersWithSpan()
            {
                ReadOnlySpan<char> spanString = someString;
                var strNumber1 = spanString.Slice(0, 2);
                var strNumber2 = spanString.Slice(2, 4);
                var strNumber3 = spanString.Slice(6);

                return (int.Parse(strNumber1), int.Parse(strNumber2), int.Parse(strNumber3));
            }
        }
}

Как вы можете видеть, теперь у нас есть новый класс под названием «Bench» и два метода с атрибутом «BenchMark» и MemoryDiagnoser в классе Bench, остальное остается прежним, и при запуске у нас будет…

Время правды!!

Чёртов повелитель драконов со своей безумной магией, что это такое????

Как видим ребята, Span почти в два раза быстрее и вообще не выделяет память!!!

Пришло время включить это в свои приложения и помочь вашей компании сэкономить несколько долларов.

Span работает с разными типами, а не только со строками, которые вы можете использовать, например, для байтов или других вариантов использования, которые есть в вашем приложении.

Чего вы ждете, вы все еще собираетесь использовать эту дорогую подстроку в своем коде???

Ребята, надеюсь, вы чему-то научились и повеселились!!!

Увидимся в следующей статье :)