Utendaji katika .NET Core

Utendaji katika .NET Core

Utendaji katika .NET Core

Salaam wote! Makala haya ni mkusanyiko wa Mbinu Bora ambazo mimi na wenzangu tumekuwa tukitumia kwa muda mrefu tunapofanya kazi kwenye miradi tofauti.

Habari juu ya mashine ambayo mahesabu yalifanywa:BenchmarkDotNet=v0.11.5, OS=Windows 10.0.18362
Intel Core i5-8250U CPU 1.60GHz (Kaby Lake R), CPU 1, 8 za kimantiki na cores 4 halisi
.NET Core SDK=3.0.100
[Mpangishi]: .NET Core 2.2.7 (CoreCLR 4.6.28008.02, CoreFX 4.6.28008.03), 64bit RyuJIT
Kiini: .NET Core 2.2.7 (CoreCLR 4.6.28008.02, CoreFX 4.6.28008.03), 64bit RyuJIT
[Mpangishi]: .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64bit RyuJIT
Kiini: .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64bit RyuJIT

Job=Core Runtime=Core

Orodha ya Orodha dhidi ya ToArray na Mizunguko


Nilipanga kuandaa habari hii na kutolewa kwa NET Core 3.0, lakini walinishinda, sitaki kuiba utukufu wa mtu mwingine na kunakili habari za watu wengine, kwa hivyo nitaonyesha tu. kiungo kwa makala nzuri ambapo kulinganisha ni ilivyoelezwa kwa undani.

Kwa niaba yangu mwenyewe, ninataka tu kuwasilisha kwako vipimo na matokeo yangu; niliongeza vitanzi vya kurudi nyuma kwao kwa wapenzi wa "mtindo wa C++" wa kuandika vitanzi.

Kanuni:

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;
        }
    }

Kasi ya utendakazi katika NET Core 2.2 na 3.0 zinakaribia kufanana. Hivi ndivyo nilivyoweza kupata NET Core 3.0:

Utendaji katika .NET Core

Utendaji katika .NET Core

Tunaweza kuhitimisha kuwa uchakataji unaorudiwa wa mkusanyiko wa Array ni haraka zaidi kwa sababu ya uboreshaji wake wa ndani na mgao dhahiri wa saizi ya mkusanyiko. Inafaa pia kukumbuka kuwa mkusanyiko wa Orodha una faida zake mwenyewe na unapaswa kutumia mkusanyiko sahihi kulingana na hesabu zinazohitajika. Hata ukiandika mantiki ya kufanya kazi na vitanzi, usisahau kuwa hii ni kitanzi cha kawaida na pia iko chini ya uboreshaji wa kitanzi unaowezekana. Nakala ilichapishwa kwa habr muda mrefu uliopita: https://habr.com/ru/post/124910/. Bado ni muhimu na inapendekezwa kusoma.

Kutupa

Mwaka mmoja uliopita, nilifanya kazi katika kampuni kwenye mradi wa urithi, katika mradi huo ilikuwa kawaida kuchakata uthibitishaji wa uwanja kupitia jaribio la kukamata-kutupa. Tayari nilielewa kuwa hii ilikuwa mantiki ya biashara isiyofaa kwa mradi huo, kwa hivyo kila inapowezekana nilijaribu kutotumia muundo kama huo. Lakini hebu tujue ni kwa nini mbinu ya kushughulikia makosa na ujenzi huo ni mbaya. Niliandika nambari ndogo kulinganisha njia hizo mbili na nikafanya alama za kila chaguo.

Kanuni:

        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;
        }

Matokeo katika .NET Core 3.0 na Core 2.2 yana matokeo sawa (.NET Core 3.0):

Utendaji katika .NET Core

Utendaji katika .NET Core

Jaribu kukamata hufanya msimbo kuwa mgumu kuelewa na huongeza muda wa utekelezaji wa programu yako. Lakini ikiwa unahitaji ujenzi huu, hupaswi kuingiza mistari hiyo ya kanuni ambayo haitarajiwi kushughulikia makosa - hii itafanya msimbo rahisi kuelewa. Kwa kweli, sio sana utunzaji wa tofauti ambao hupakia mfumo, lakini badala yake utupaji wa makosa yenyewe kupitia utupaji mpya wa Ubaguzi.

Vighairi vya kutupa ni polepole kuliko darasa fulani ambalo litakusanya hitilafu katika umbizo linalohitajika. Ikiwa unachakata fomu au data fulani na unajua wazi kosa linapaswa kuwa nini, kwa nini usilichakate?

Haupaswi kuandika muundo mpya wa Exception() ikiwa hali hii sio ya kipekee. Kushughulikia na kutupa ubaguzi ni ghali sana !!!

Kwa Chini, Kwa ChiniInvariant, Juu, JuuInvariant

Kwa zaidi ya miaka 5 ya uzoefu wangu wa kufanya kazi kwenye jukwaa la .NET, nimekutana na miradi mingi ambayo ilitumia kulinganisha kamba. Pia niliona picha ifuatayo: kulikuwa na suluhisho moja la Biashara na miradi mingi, ambayo kila moja ilifanya kulinganisha kwa kamba tofauti. Lakini ni nini kinachopaswa kutumiwa na jinsi ya kuiunganisha? Kwenye kitabu CLR kupitia C# na Richter, nilisoma habari kwamba njia ya ToUpperInvariant() ni haraka kuliko ToLowerInvariant().

Nukuu kutoka kwa kitabu:

Utendaji katika .NET Core

Bila shaka, sikuamini na niliamua kufanya majaribio kisha kwenye .NET Framework na matokeo yalinishtua - zaidi ya 15% ya ongezeko la utendaji. Kisha, nilipofika kazini asubuhi iliyofuata, nilionyesha vipimo hivi kwa wakuu wangu na kuwapa ufikiaji wa nambari ya chanzo. Baada ya hayo, miradi 2 kati ya 14 ilibadilishwa ili kushughulikia vipimo vipya, na kwa kuzingatia kwamba miradi hii miwili ilikuwepo ya kuchakata meza kubwa za Excel, matokeo yalikuwa muhimu zaidi kwa bidhaa.

Pia ninawasilisha kwako vipimo vya matoleo tofauti ya .NET Core, ili kila mmoja wenu afanye chaguo kuelekea suluhisho bora zaidi. Na ninataka tu kuongeza kuwa katika kampuni ninayofanya kazi, tunatumia ToUpper() kulinganisha kamba.

Kanuni:

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();
        }

Utendaji katika .NET Core

Utendaji katika .NET Core

Katika .NET Core 3.0, ongezeko la kila moja ya njia hizi ni ~x2 na kusawazisha utekelezaji kati yao wenyewe.

Utendaji katika .NET Core

Utendaji katika .NET Core

Mkusanyiko wa Tier

Katika makala yangu ya mwisho nilieleza uamilifu huu kwa ufupi, ningependa kusahihisha na kuongezea maneno yangu. Ukusanyaji wa viwango vingi huharakisha muda wa kuanza kwa suluhisho lako, lakini unajitolea kuwa sehemu za msimbo wako zitakusanywa kuwa toleo lililoboreshwa zaidi chinichini, ambalo linaweza kutambulisha kichwa kidogo. Pamoja na ujio wa NET Core 3.0, muda wa kujenga kwa miradi iliyo na ujumuishaji wa tier umepungua na hitilafu zinazohusiana na teknolojia hii zimerekebishwa. Hapo awali, teknolojia hii ilisababisha makosa katika maombi ya kwanza katika ASP.NET Core na kufungia wakati wa kujenga kwanza katika hali ya mkusanyiko wa ngazi mbalimbali. Kwa sasa imewezeshwa kwa chaguomsingi katika .NET Core 3.0, lakini unaweza kuizima ukipenda. Ikiwa uko katika nafasi ya kiongozi wa timu, mwandamizi, katikati, au wewe ni mkuu wa idara, basi lazima uelewe kwamba maendeleo ya haraka ya mradi huongeza thamani ya timu na teknolojia hii itakuruhusu kuokoa muda kwa watengenezaji wote wawili. na wakati wa mradi wenyewe.

.NET ngazi juu

Boresha toleo lako la NET Framework / .NET Core. Mara nyingi, kila toleo jipya hutoa faida ya ziada ya utendaji na kuongeza vipengele vipya.

Lakini ni faida gani hasa? Hebu tuangalie baadhi yao:

  • .NET Core 3.0 ilianzisha picha za R2R ambazo zitapunguza muda wa kuanza kwa programu za .NET Core.
  • Na toleo la 2.2, Mkusanyiko wa Tier ulionekana, shukrani ambayo waandaaji wa programu watatumia muda mdogo kuzindua mradi.
  • Usaidizi kwa Viwango vipya vya NET.
  • Usaidizi wa toleo jipya la lugha ya programu.
  • Uboreshaji, kwa kila toleo jipya uboreshaji wa maktaba za msingi Mkusanyiko/Muundo/Mtiririko/Kamba/Regex na mengi zaidi huboreshwa. Ikiwa unahama kutoka .NET Framework hadi .NET Core, utapata utendakazi mkubwa zaidi kutoka kwenye boksi. Kama mfano, ninaambatisha kiungo kwa baadhi ya uboreshaji ambao uliongezwa kwa .NET Core 3.0: https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-core-3-0/

Utendaji katika .NET Core

Hitimisho

Unapoandika msimbo, inafaa kuzingatia vipengele tofauti vya mradi wako na kutumia vipengele vya lugha yako ya programu na jukwaa ili kufikia matokeo bora. Ningefurahi ikiwa utashiriki maarifa yako yanayohusiana na uboreshaji katika .NET.

Unganisha kwa github

Chanzo: mapenzi.com

Kuongeza maoni