.NET Core дээрх гүйцэтгэл

.NET Core дээрх гүйцэтгэл

.NET Core дээрх гүйцэтгэл

Сайн уу! Энэхүү нийтлэл нь миний болон миний хамт олон янз бүрийн төсөл дээр ажиллахдаа удаан хугацаанд ашиглаж ирсэн шилдэг туршлагуудын цуглуулга юм.

Тооцоолол хийсэн машины талаархи мэдээлэл:BenchmarkDotNet=v0.11.5, үйлдлийн систем=Windows 10.0.18362
Intel Core i5-8250U CPU 1.60GHz (Kaby Lake R), 1 CPU, 8 логик, 4 физик цөм
.NET Core SDK=3.0.100
[Хост]: .NET Core 2.2.7 (CoreCLR 4.6.28008.02, CoreFX 4.6.28008.03), 64 бит RyuJIT
Үндсэн: .NET Core 2.2.7 (CoreCLR 4.6.28008.02, CoreFX 4.6.28008.03), 64 бит RyuJIT
[Хост]: .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64 бит RyuJIT
Үндсэн: .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64 бит RyuJIT

Ажил=Үндсэн Ажиллах цаг=Үндсэн

ToArray ба мөчлөгийн эсрэг ToList


Би энэ мэдээллийг .NET Core 3.0 хувилбарыг гаргаснаар бэлтгэхээр төлөвлөж байсан ч тэд намайг ялсан, би бусдын алдар нэрийг хулгайлж, бусдын мэдээллийг хуулахыг хүсэхгүй байна, тиймээс би зүгээр л онцлон хэлье. харьцуулалтыг дэлгэрэнгүй тайлбарласан сайн нийтлэлийн холбоос.

Би өөрийнхөө нэрийн өмнөөс хэмжилт, үр дүнгээ та бүхэнд танилцуулахыг хүсч байна, би "С++ хэв маяг" бичих гогцоо сонирхогчдод зориулж урвуу гогцоо нэмсэн.

код:

public class Bench
    {
        private List<int> _list;
        private int[] _array;

        [Params(100000, 10000000)] public int N;

        [GlobalSetup]
        public void Setup()
        {
            const int MIN = 1;
            const int MAX = 10;
            Random random = new Random();
            _list = Enumerable.Repeat(0, N).Select(i => random.Next(MIN, MAX)).ToList();
            _array = _list.ToArray();
        }

        [Benchmark]
        public int ForList()
        {
            int total = 0;
            for (int i = 0; i < _list.Count; i++)
            {
                total += _list[i];
            }

            return total;
        }
        
        [Benchmark]
        public int ForListFromEnd()
        {
            int total = 0;t
            for (int i = _list.Count-1; i > 0; i--)
            {
                total += _list[i];
            }

            return total;
        }

        [Benchmark]
        public int ForeachList()
        {
            int total = 0;
            foreach (int i in _list)
            {
                total += i;
            }

            return total;
        }

        [Benchmark]
        public int ForeachArray()
        {
            int total = 0;
            foreach (int i in _array)
            {
                total += i;
            }

            return total;
        }

        [Benchmark]
        public int ForArray()
        {
            int total = 0;
            for (int i = 0; i < _array.Length; i++)
            {
                total += _array[i];
            }

            return total;
        }
        
        [Benchmark]
        public int ForArrayFromEnd()
        {
            int total = 0;
            for (int i = _array.Length-1; i > 0; i--)
            {
                total += _array[i];
            }

            return total;
        }
    }

.NET Core 2.2 болон 3.0-ийн гүйцэтгэлийн хурд бараг ижил байна. Би .NET Core 3.0-д юу авч чадсан бэ:

.NET Core дээрх гүйцэтгэл

.NET Core дээрх гүйцэтгэл

Дотор оновчлол болон цуглуулгын хэмжээг тодорхой хуваарилсны улмаас массив цуглуулгыг давтах боловсруулалт илүү хурдан байдаг гэж бид дүгнэж болно. Жагсаалтын цуглуулга нь өөрийн гэсэн давуу талтай бөгөөд шаардлагатай тооцооллоос хамааран зөв цуглуулгыг ашиглах ёстой гэдгийг санах нь зүйтэй. Хэдийгээр та гогцоотой ажиллах логик бичдэг байсан ч энэ нь ердийн гогцоо бөгөөд энэ нь давталтыг оновчтой болгох боломжтой гэдгийг мартаж болохгүй. Хабр дээр нэлээд удаан хугацааны өмнө нийтлэл хэвлэгдсэн: https://habr.com/ru/post/124910/. Энэ нь хамааралтай хэвээр байгаа бөгөөд уншихыг зөвлөж байна.

Шид

Жилийн өмнө би нэгэн компанид хуучин төсөл дээр ажиллаж байсан бөгөөд энэ төсөлд оролдлого барих-шидэлт хийх замаар талбайн баталгаажуулалтыг боловсруулах нь хэвийн үзэгдэл байв. Энэ нь төслийн хувьд эрүүл бус бизнесийн логик гэдгийг би тэр үед аль хэдийн ойлгосон тул аль болох ийм загварыг ашиглахгүй байхыг хичээсэн. Гэхдээ ийм бүтээн байгуулалттай холбоотой алдааг шийдвэрлэх хандлага яагаад муу байгааг олж мэдье. Би хоёр хандлагыг харьцуулахын тулд жижиг код бичиж, сонголт бүрийн жишиг үзүүлэлтүүдийг хийсэн.

код:

        public bool ContainsHash()
        {
            bool result = false;
            foreach (var file in _files)
            {
                var extension = Path.GetExtension(file);
                if (_hash.Contains(extension))
                    result = true;
            }

            return result;
        }

        public bool ContainsHashTryCatch()
        {
            bool result = false;
            try
            {
                foreach (var file in _files)
                {
                    var extension = Path.GetExtension(file);
                    if (_hash.Contains(extension))
                        result = true;
                }
                
                if(!result) 
                    throw new Exception("false");
            }
            catch (Exception e)
            {
                result = false;
            }

            return result;
        }

.NET Core 3.0 болон Core 2.2 дээрх үр дүн ижил төстэй байна (.NET Core 3.0):

.NET Core дээрх гүйцэтгэл

.NET Core дээрх гүйцэтгэл

Catch-г оролдох нь кодыг ойлгоход хэцүү болгож, таны програмыг гүйцэтгэх хугацааг уртасгана. Гэхдээ хэрэв танд ийм бүтэц хэрэгтэй бол алдаа гаргахгүй гэж тооцогдох кодын мөрүүдийг оруулах ёсгүй - энэ нь кодыг ойлгоход хялбар болгоно. Үнэн хэрэгтээ системийг ачаалах нь онцгой тохиолдлуудыг зохицуулахаас гадна throw шинэ Exception бүтэцээр дамжуулан өөрөө алдаа гаргадаг.

Үл хамаарах зүйлүүдийг хаях нь алдааг шаардлагатай форматаар цуглуулах зарим ангиас удаан байдаг. Хэрэв та маягт эсвэл зарим өгөгдлийг боловсруулж байгаа бөгөөд ямар алдаа гарах ёстойг тодорхой мэдэж байгаа бол яагаад үүнийг боловсруулж болохгүй гэж?

Хэрэв энэ нөхцөл байдал онцгой биш бол та throw new Exception() бүтцийг бичих ёсгүй. Үл хамаарах зүйлтэй харьцах, хаях нь маш үнэтэй юм!!!

ToLower, ToLowerInvariant, ToUpper, ToUpperInvariant

.NET платформ дээр ажилласан 5 жилийн турш би string matching ашигласан олон төсөлтэй танилцсан. Би бас дараах зургийг харсан: олон төсөлтэй нэг Enterprise шийдэл байсан бөгөөд тэдгээр нь тус бүр нь мөрийн харьцуулалтыг өөр өөрөөр гүйцэтгэдэг. Гэхдээ юуг ашиглах, яаж нэгтгэх вэ? Richter-ийн бичсэн CLR via C# номноос ToUpperInvariant() арга нь ToLowerInvariant()-аас хурдан гэсэн мэдээллийг уншсан.

Номноос ишлэл:

.NET Core дээрх гүйцэтгэл

Мэдээжийн хэрэг, би үүнд итгэхгүй байсан бөгөөд дараа нь .NET Framework дээр туршилт хийхээр шийдсэн бөгөөд үр дүн нь намайг цочирдуулсан - гүйцэтгэлийн өсөлт 15% -иас илүү. Дараа нь би маргааш өглөө ажилдаа ирэхдээ эдгээр хэмжүүрүүдийг дарга нартаа үзүүлж, эх кодтой танилцах боломжийг олгосон. Үүний дараа 2 төслөөс 14-ыг нь шинэ хэмжилтэнд тохируулан өөрчилсөн бөгөөд эдгээр хоёр төсөл нь Excel-ийн асар том хүснэгтүүдийг боловсруулахад зориулагдсан гэж үзвэл үр дүн нь бүтээгдэхүүний хувьд чухал ач холбогдолтой байв.

Мөн би та бүхэнд .NET Core-ийн янз бүрийн хувилбаруудын хэмжилтүүдийг танилцуулж байна, ингэснээр та хүн бүр хамгийн оновчтой шийдлийг сонгох боломжтой болно. Миний ажилладаг компанид бид мөрүүдийг харьцуулахын тулд ToUpper() ашигладаг гэдгийг л нэмж хэлмээр байна.

код:

public const string defaultString =  "VXTDuob5YhummuDq1PPXOHE4PbrRjYfBjcHdFs8UcKSAHOCGievbUItWhU3ovCmRALgdZUG1CB0sQ4iMj8Z1ZfkML2owvfkOKxBCoFUAN4VLd4I8ietmlsS5PtdQEn6zEgy1uCVZXiXuubd0xM5ONVZBqDu6nOVq1GQloEjeRN8jXrj0MVUexB9aIECs7caKGddpuut3";

        [Benchmark]
        public bool ToLower()
        {
            return defaultString.ToLower() == defaultString.ToLower();
        }

        [Benchmark]
        public bool ToLowerInvariant()
        {
            return defaultString.ToLowerInvariant() == defaultString.ToLowerInvariant();
        }

        [Benchmark]
        public bool ToUpper()
        {
            return defaultString.ToUpper() == defaultString.ToUpper();
        }

        [Benchmark]
        public bool ToUpperInvariant()
        {
            return defaultString.ToUpperInvariant() == defaultString.ToUpperInvariant();
        }

.NET Core дээрх гүйцэтгэл

.NET Core дээрх гүйцэтгэл

.NET Core 3.0-д эдгээр аргууд бүрийн өсөлт нь ~x2 бөгөөд хэрэгжилтийг хооронд нь тэнцвэржүүлдэг.

.NET Core дээрх гүйцэтгэл

.NET Core дээрх гүйцэтгэл

Түвшингийн эмхэтгэл

Сүүлчийн нийтлэлдээ би энэ функцийг товч тайлбарлаж, үгээ засаж, нэмэлт оруулахыг хүсч байна. Олон түвшний эмхэтгэл нь таны шийдлийг эхлүүлэх хугацааг хурдасгадаг боловч та кодын зарим хэсгийг арын дэвсгэр дээр илүү оновчтой хувилбар болгон хөрвүүлэхийг золиослох бөгөөд энэ нь бага хэмжээний нэмэлт зардал үүсгэж болзошгүй юм. NET Core 3.0 гарч ирснээр түвшний эмхэтгэлийг идэвхжүүлсэн төслүүдийг бүтээх хугацаа багасч, энэ технологитой холбоотой алдаануудыг зассан. Өмнө нь энэ технологи нь ASP.NET Core-ийн эхний хүсэлтүүдэд алдаа гаргахад хүргэдэг байсан бөгөөд олон түвшний эмхэтгэлийн горимд эхний бүтээх явцад хөлддөг. Энэ нь одоогоор .NET Core 3.0-д анхдагчаар идэвхжсэн боловч хэрэв хүсвэл та үүнийг идэвхгүй болгож болно. Хэрэв та багийн ахлагч, ахлах, дунд, эсвэл хэлтсийн дарга зэрэг албан тушаал хашиж байгаа бол төслийн хурдацтай боловсруулалт нь багийн үнэ цэнийг нэмэгдүүлж, энэхүү технологи нь хоёр хөгжүүлэгчийн цагийг хэмнэх боломжийг танд олгоно гэдгийг ойлгох ёстой. мөн төслийн цаг хугацаа өөрөө.

.NET түвшин дээшиллээ

.NET Framework / .NET Core хувилбараа шинэчилнэ үү. Ихэнхдээ шинэ хувилбар бүр нэмэлт гүйцэтгэлийг нэмэгдүүлж, шинэ боломжуудыг нэмж өгдөг.

Гэхдээ яг ямар ашиг тустай вэ? Тэдгээрийн заримыг нь харцгаая:

  • .NET Core 3.0 нь .NET Core програмуудыг эхлүүлэх хугацааг багасгах R2R дүрсийг нэвтрүүлсэн.
  • 2.2 хувилбарын тусламжтайгаар Tier Compilation гарч ирсэн бөгөөд үүний ачаар програмистууд төсөл эхлүүлэхэд бага цаг зарцуулах болно.
  • Шинэ .NET стандартуудын дэмжлэг.
  • Програмчлалын хэлний шинэ хувилбарыг дэмжих.
  • Оновчлол, шинэ хувилбар бүрээр Collection/Struct/Stream/String/Regex болон бусад үндсэн сангуудын оновчлол сайжирна. Хэрэв та .NET Framework-оос .NET Core руу шилжиж байгаа бол гүйцэтгэлийн өсөлтийг хайрцагнаас авах болно. Жишээ болгон би .NET Core 3.0-д нэмсэн зарим оновчлолын холбоосыг хавсаргав: https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-core-3-0/

.NET Core дээрх гүйцэтгэл

дүгнэлт

Код бичихдээ хамгийн сайн үр дүнд хүрэхийн тулд төслийнхөө өөр өөр талуудад анхаарлаа хандуулж, програмчлалын хэл, платформын онцлогийг ашиглах нь зүйтэй. Та .NET дээр оновчлолтой холбоотой мэдлэгээ хуваалцвал би баяртай байх болно.

Github руу холбох

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх