.NET Core-da ishlash

.NET Core-da ishlash

.NET Core-da ishlash

Hammaga salom! Ushbu maqola men va hamkasblarim uzoq vaqtdan beri turli loyihalar ustida ishlaganda foydalanayotgan ilg‘or tajribalar to‘plamidir.

Hisob-kitoblar amalga oshirilgan mashina haqida ma'lumot:BenchmarkDotNet=v0.11.5, OS=Windows 10.0.18362
Intel Core i5-8250U CPU 1.60GHz (Kaby Lake R), 1 protsessor, 8 mantiqiy va 4 jismoniy yadro
.NET Core SDK=3.0.100
[Xost]: .NET Core 2.2.7 (CoreCLR 4.6.28008.02, CoreFX 4.6.28008.03), 64bit RyuJIT
Yadro: .NET Core 2.2.7 (CoreCLR 4.6.28008.02, CoreFX 4.6.28008.03), 64bit RyuJIT
[Xost]: .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64bit RyuJIT
Yadro: .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64bit RyuJIT

Ish = Asosiy ish vaqti = Yadro

ToArray va Cyclesga qarshi ToList


Men ushbu ma'lumotni .NET Core 3.0 versiyasini chiqarish bilan tayyorlashni rejalashtirgan edim, lekin ular meni mag'lub etishdi, men birovning shon-shuhratini o'g'irlashni va boshqa odamlarning ma'lumotlarini nusxalashni xohlamayman, shuning uchun men shunchaki ta'kidlayman. taqqoslash batafsil tavsiflangan yaxshi maqolaga havola.

Men o'z nomimdan sizlarga o'z o'lchovlarim va natijalarimni taqdim etmoqchiman; "C++ uslubidagi" yozish tsikllarini sevuvchilar uchun ularga teskari halqalarni qo'shdim.

kodi:

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 va 3.0 da ishlash tezligi deyarli bir xil. .NET Core 3.0 da nimalarga erisha oldim:

.NET Core-da ishlash

.NET Core-da ishlash

Xulosa qilishimiz mumkinki, massiv to'plamini iterativ qayta ishlash uning ichki optimallashtirishlari va to'plam hajmini aniq taqsimlash tufayli tezroq bo'ladi. Shuni ham yodda tutish kerakki, List to'plamining o'ziga xos afzalliklari bor va siz kerakli hisob-kitoblarga qarab to'g'ri to'plamdan foydalanishingiz kerak. Agar siz looplar bilan ishlash uchun mantiqni yozsangiz ham, bu oddiy tsikl ekanligini unutmang va u ham mumkin bo'lgan tsiklni optimallashtirishga bog'liq. Habr-da ancha oldin maqola chop etilgan: https://habr.com/ru/post/124910/. U hali ham dolzarb va o'qish tavsiya etiladi.

Otish

Bir yil oldin men kompaniyada eski loyihada ishladim, bu loyihada dala tekshiruvini try-catch-throw konstruksiyasi orqali qayta ishlash odatiy hol edi. Men o'shanda bu loyiha uchun nosog'lom biznes mantig'i ekanligini allaqachon tushungan edim, shuning uchun iloji boricha bunday dizayndan foydalanmaslikka harakat qildim. Ammo keling, nima uchun bunday qurilish bilan xatolarni bartaraf etishning yondashuvi yomon ekanligini aniqlaylik. Men ikkita yondashuvni solishtirish uchun kichik kod yozdim va har bir variant uchun benchmarklar qildim.

kodi:

        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 va Core 2.2 natijalari xuddi shunday natijaga ega (.NET Core 3.0):

.NET Core-da ishlash

.NET Core-da ishlash

Try catch kodni tushunishni qiyinlashtiradi va dasturingizning ishlash vaqtini oshiradi. Ammo agar sizga ushbu konstruktsiya kerak bo'lsa, xatoliklarni bartaraf etishi kutilmaydigan kod qatorlarini kiritmasligingiz kerak - bu kodni tushunishni osonlashtiradi. Haqiqatdan ham, tizimni yuklaydigan istisnolar bilan ishlash emas, balki o'z-o'zidan xatolarni o'chirish yangi Istisno konstruktsiyasi orqali yuborishdir.

Istisnolarni tashlash xatoni kerakli formatda to'playdigan ba'zi sinflarga qaraganda sekinroq. Agar siz shakl yoki ba'zi ma'lumotlarni qayta ishlayotgan bo'lsangiz va xato nima bo'lishi kerakligini aniq bilsangiz, nega uni qayta ishlamaysiz?

Agar bu holat istisno bo'lmasa, throw new Exception() konstruktsiyasini yozmasligingiz kerak. Istisnoni qo'llash va tashlash juda qimmat !!!

ToLower, ToLowerInvariant, ToUpper, ToUpperInvariant

.NET platformasida ishlagan 5 yillik tajribam davomida string moslashuvidan foydalangan ko'plab loyihalarga duch keldim. Men quyidagi rasmni ham ko'rdim: ko'plab loyihalarga ega bo'lgan bitta Enterprise yechimi bor edi, ularning har biri string taqqoslashni boshqacha amalga oshirdi. Lekin nimadan foydalanish kerak va uni qanday birlashtirish kerak? Rixterning C# orqali CLR kitobida men ToUpperInvariant() usuli ToLowerInvariant() dan tezroq ekanligi haqidagi ma'lumotni o'qidim.

Kitobdan parcha:

.NET Core-da ishlash

Albatta, men bunga ishonmadim va .NET Framework-da ba'zi testlarni o'tkazishga qaror qildim va natija meni hayratda qoldirdi - unumdorlikning 15% dan ortiq o'sishi. Keyin, ertasi kuni ertalab ishga kelganimda, men bu o'lchovlarni rahbarlarimga ko'rsatdim va ularga manba kodiga kirish huquqini berdim. Shundan so'ng, 2 ta loyihadan 14 tasi yangi o'lchovlarga moslashish uchun o'zgartirildi va bu ikkita loyiha ulkan Excel jadvallarini qayta ishlash uchun mavjud ekanligini hisobga olsak, natija mahsulot uchun ahamiyatli bo'ldi.

Men sizga .NET Core ning turli versiyalari uchun o'lchovlarni ham taqdim etaman, shunda har biringiz eng maqbul echimni tanlash imkoniyatiga ega bo'lasiz. Va shuni qo'shmoqchimanki, men ishlayotgan kompaniyada biz satrlarni solishtirish uchun ToUpper() dan foydalanamiz.

kodi:

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-da ishlash

.NET Core-da ishlash

.NET Core 3.0 da ushbu usullarning har biri uchun o'sish ~x2 ni tashkil qiladi va amalga oshirishni o'zaro muvozanatlashtiradi.

.NET Core-da ishlash

.NET Core-da ishlash

Darajali kompilyatsiya

Oxirgi maqolamda men ushbu funktsiyani qisqacha tasvirlab berdim, men so'zlarimni to'g'rilash va to'ldirishni xohlayman. Ko'p darajali kompilyatsiya sizning yechimingizning ishga tushirish vaqtini tezlashtiradi, lekin siz kodingizning qismlari fonda yanada optimallashtirilgan versiyaga kompilyatsiya qilinishini qurbon qilasiz, bu esa kichik xarajatlarni keltirib chiqarishi mumkin. NET Core 3.0 ning paydo bo'lishi bilan darajali kompilyatsiya yoqilgan loyihalarni qurish vaqti qisqardi va ushbu texnologiya bilan bog'liq xatolar tuzatildi. Ilgari, bu texnologiya ASP.NET Core’dagi birinchi so‘rovlarda xatoliklarga olib keldi va ko‘p darajali kompilyatsiya rejimida birinchi qurish vaqtida muzlab qoldi. Hozirda u .NET Core 3.0 da sukut bo'yicha yoqilgan, lekin agar xohlasangiz, uni o'chirib qo'yishingiz mumkin. Agar siz guruh rahbari, katta, o'rta yoki siz bo'lim boshlig'i bo'lsangiz, loyihani tezkor ishlab chiqish jamoaning qiymatini oshirishini va bu texnologiya ikkala ishlab chiquvchi uchun vaqtni tejashga imkon berishini tushunishingiz kerak. va loyihaning o'zi.

.NET darajasiga ko'tarildi

.NET Framework / .NET Core versiyasini yangilang. Ko'pincha, har bir yangi versiya qo'shimcha unumdorlikni oshiradi va yangi xususiyatlarni qo'shadi.

Lekin qanday foyda bor? Keling, ulardan ba'zilarini ko'rib chiqaylik:

  • .NET Core 3.0 R2R tasvirlarini taqdim etdi, bu esa .NET Core ilovalarini ishga tushirish vaqtini qisqartiradi.
  • 2.2 versiyasi bilan Tier Compilation paydo bo'ldi, buning natijasida dasturchilar loyihani ishga tushirishga kamroq vaqt sarflashadi.
  • Yangi .NET standartlarini qo'llab-quvvatlash.
  • Dasturlash tilining yangi versiyasini qo'llab-quvvatlash.
  • Optimallashtirish, har bir yangi versiya bilan Collection/Struct/Stream/String/Regex va boshqa ko'p narsalarning asosiy kutubxonalarini optimallashtirish yaxshilanadi. Agar siz .NET Framework-dan .NET Core-ga o'tayotgan bo'lsangiz, siz qutidan katta ish unumdorligini olasiz. Misol tariqasida, men .NET Core 3.0 ga qo‘shilgan ba’zi optimallashtirishlarga havolani biriktiraman: https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-core-3-0/

.NET Core-da ishlash

xulosa

Kod yozishda loyihangizning turli jihatlariga e'tibor qaratish va eng yaxshi natijaga erishish uchun dasturlash tili va platformangizning xususiyatlaridan foydalanishga arziydi. .NETda optimallashtirishga oid bilimlaringizni baham ko'rsangiz xursand bo'laman.

Github ga havola

Manba: www.habr.com

a Izoh qo'shish