Как да сравняваме C # кода с помощта на BenchmarkDotNet

BenchmarkDotNet е олекотена, мощна .NET библиотека с отворен код, която може да трансформира вашите методи в референтни показатели, да проследява тези методи и след това да предоставя информация за заснетите данни за производителността. Лесно е да се напишат BenchmarkDotNet бенчмаркове, а резултатите от процеса на бенчмаркинг също са удобни за потребителя.

Можете да се възползвате от BenchmarkDotNet, за да сравните приложенията .NET Framework и .NET Core. В тази статия ще разгледаме как можем да работим с BenchmarkDotNet в .NET Core. Можете да намерите BenchmarkDotNet на GitHub.

За да работите с примерите за кодове, предоставени в тази статия, трябва да имате Visual Studio 2019 инсталиран във вашата система. Ако все още нямате копие, можете да изтеглите Visual Studio 2019 тук. 

Създайте проект за конзолно приложение в Visual Studio

Първо, нека създадем проект за приложение на конзола .NET Core в Visual Studio. Ако приемем, че Visual Studio 2019 е инсталиран във вашата система, следвайте стъпките, описани по-долу, за да създадете нов проект за приложение на конзола .NET Core в Visual Studio.

  1. Стартирайте Visual Studio IDE.
  2. Кликнете върху „Създаване на нов проект“.
  3. В прозореца „Създаване на нов проект“ изберете „Console App (.NET Core)“ от показания списък с шаблони.
  4. Щракнете върху Напред.
  5. В показания след това прозорец „Конфигуриране на вашия нов проект“ посочете името и местоположението на новия проект.
  6. Щракнете върху Създаване.

Това ще създаде нов проект за приложение на конзола .NET Core в Visual Studio 2019.

Имайте предвид, че когато създавате проект на конзолно приложение, полученият клас на програмата (генериран автоматично във файла Program.cs) ще изглежда така:

клас Програма

{

   static void Main (низ [] аргументи)

  {

      Console.WriteLine („Здравей, Свят!“);

  }

}

Ще използваме този проект и клас на програма за работа с BenchmarkDotNet в следващите раздели на тази статия.

Инсталирайте пакета BenchmarkDotNet NuGet

За да работите с BenchmarkDotNet, трябва да инсталирате пакета BenchmarkDotNet. Можете да направите това или чрез NuGet Package Manager вътре в IDE на Visual Studio 2019, или като изпълните следната команда в конзолата NuGet Package Manager:

Инсталирайте пакета BenchmarkDotNet

Защо бенчмарк код?

Бенчмарк е измерване или набор от измервания, свързани с изпълнението на даден код в приложение. Бенчмаркинг кодът е от съществено значение за разбирането на показателите за ефективност на методите във вашето приложение. Винаги е добър подход да имате под ръка метриките, когато оптимизирате кода. За нас е много важно да знаем дали промените, направени в кода, са подобрили или влошили работата. Бенчмаркингът също ви помага да стесните частите от кода в приложението, които се нуждаят от рефакторинг.

Стъпки за бенчмаркинг на код с помощта на BenchmarkDotNet

За да стартирате BenchmarkDotNet във вашето приложение .NET Framework или .NET Core, трябва да изпълните следните стъпки:

  1. Добавете необходимия пакет NuGet
  2. Добавете Benchmark атрибути към вашите методи
  3. Създайте екземпляр на BenchmarkRunner
  4. Стартирайте приложението в режим на освобождаване

Създайте клас за сравнителен анализ в .NET Core

Отворете файла Program.cs и напишете следния код там.

  [MemoryDiagnoser]

   публичен клас MemoryBenchmarkerDemo

    {

        int NumberOfItems = 100000;

        [Бенчмарк]

        публичен низ ConcatStringsUsingStringBuilder ()

        {

            var sb = нов StringBuilder ();

            за (int i = 0; i <NumberOfItems; i ++)

            {

                sb.Append ("Hello World!" + i);

            }

            върнете sb.ToString ();

        }

        [Бенчмарк]

        публичен низ ConcatStringsUsingGenericList ()

        {

            var list = нов списък (NumberOfItems);

            за (int i = 0; i <NumberOfItems; i ++)

            {

                list.Add ("Hello World!" + i);

            }

            връща списък.ToString ();

        }

    }

Горната програма илюстрира как можете да пишете методи за сравнителен анализ. Обърнете внимание на използването на атрибута Benchmark върху всеки от методите, които трябва да бъдат сравнени.

В основния метод на файла Program.cs трябва да посочите началната начална точка - класът BenchmarkRunner. Това е начин за информиране на BenchmarkDotNet за изпълнение на бенчмаркове за посочения клас. Така че, заменете кода по подразбиране на метода Main във файла Program.cs, като използвате следния кодов фрагмент.

static void Main (низ [] аргументи)

{

   var резюме = BenchmarkRunner.Run ();

}

Стартирайте бенчмарка във вашето приложение .NET Core

Ако стартирате приложението в режим за отстраняване на грешки, ето съобщението за грешка, което ще видите:

Когато сравнявате, винаги трябва да сте сигурни, че стартирате проекта си в режим на освобождаване. Причината е, че по време на компилацията кодът се оптимизира по различен начин както за отстраняване на грешки, така и за режими на освобождаване. Компилаторът C # прави няколко оптимизации в режим на освобождаване, които не са налични в режим за отстраняване на грешки.

Следователно трябва да стартирате проекта си само в режим на освобождаване. За да стартирате сравнителен анализ, посочете следната команда в командния ред на Visual Studio.

dotnet run -p BenchmarkDotNetDemo.csproj -c Release

За най-добри резултати трябва да се уверите, че всички приложения са затворени и всички ненужни процеси са спрени, преди да стартирате бенчмаркове.

Обърнете внимание, че ако не посочите конфигурационния параметър, тогава изпълнението ще се опита да направи бенчмаркинг върху неоптимизиран код за отстраняване на грешки. И ще ви бъде представена същата грешка, показана на фигура 1.

Анализирайте резултатите от сравнителния анализ

След като изпълнението на процеса на сравнителен анализ приключи, резюме на резултатите ще се покаже в прозореца на конзолата. Разделът с резюме съдържа информация, свързана със средата, в която са изпълнени бенчмарковете, като например версията BenchmarkDotNet, операционна система, компютърен хардуер, версия .NET, информация за компилатора и информация, свързана с производителността на приложението.

Няколко файла също ще бъдат създадени в папката BenchmarkDotNet.Artifacts под основната папка на приложението. Ето обобщение на резултатите. 

Както е видно от обобщението, показано на фигура 2, за всеки бенчмаркиран метод ще видите ред данни, които определят метриките на производителността, като средно време за изпълнение, колекции от Gen 1, Gen 1, Gen 2 и т.н.

При изследване на резултатите, показани на Фигура 3, можете да видите, че ConcatStringUsingGenericList е много по-бърз от метода ConcatStringUsingStringBuilder. Можете също така да видите, че има много повече разпределения след стартиране на метода ConcatStringUsingStringBuilder.

Сега добавете атрибута RankColumn отгоре на класа MemoryBenchmarkerDemo. Това ще добави допълнителна колона към изхода, указвайки кой метод е по-бърз. Стартирайте отново процеса на сравнителен анализ, като използвате следната команда.

dotnet run -p BenchmarkDotNetDemo.csproj -c Release

Когато стартирате тази команда, процесът на сравнителен анализ започва и показва изхода, след като процесът на сравнителен анализ е изпълнен успешно. Фигура 4 по-долу показва резултата с добавен RankColumn. 

BenchmarkDotNet е приятен инструмент, който предоставя лесен начин за вземане на информирано решение относно показателите за ефективност на вашето приложение. В BenchmarkDotNet извикването на метод, който има зададен атрибут Benchmark, е известно като операция. Итерацията е името, дадено на колекция от няколко операции. 

Можете да разгледате демонстрационно приложение ASP.NET Core, което илюстрира няколко начина за сравняване на кода. Можете да получите приложението от репозитория на ASP.NET на GitHub. 

Как да направите повече в C #: 

  • Как да тествате статични методи в C #
  • Как да рефакторирам Бог обекти в C #
  • Как да използвам ValueTask в C #
  • Как да използваме неизменност в C
  • Как да използвам const, readonly и static в C #
  • Как да използвам анотации на данни в C #
  • Как да работите с GUID в C # 8
  • Кога да се използва абстрактен клас срещу интерфейс в C #
  • Как да работя с AutoMapper в C #
  • Как да използвам ламбда изрази в C #
  • Как да работя с Action, Func и Predicate делегати в C #
  • Как да работя с делегати в C #
  • Как да внедрите прост регистратор в C #
  • Как да работя с атрибути в C #
  • Как да работя с log4net в C #
  • Как да приложим шаблона за проектиране на хранилището в C #
  • Как да работя с отражение в C #
  • Как да работя с файлова система за наблюдение в C #
  • Как да извършите мързелива инициализация в C #
  • Как да работите с MSMQ в C #
  • Как да работя с методи за разширение в C #
  • Как да използваме ламбда изрази в C #
  • Кога да се използва летливата ключова дума в C #
  • Как да използвам ключовата дума yield в C #
  • Как да приложим полиморфизъм в C #
  • Как да изградите свой собствен планировчик на задачи в C #
  • Как да работя с RabbitMQ в C #
  • Как да работите с кортеж в C #
  • Проучване на виртуални и абстрактни методи в C #
  • Как да използваме Dapper ORM в C #
  • Как да използвам шаблона за дизайн на мухата в C #