Afköst í .NET Core

Afköst í .NET Core

Afköst í .NET Core

Hæ allir! Þessi grein er samansafn af bestu starfsvenjum sem ég og samstarfsmenn mínir höfum notað í langan tíma þegar unnið er að mismunandi verkefnum.

Upplýsingar um vélina sem útreikningarnir voru gerðir á:BenchmarkDotNet=v0.11.5, OS=Windows 10.0.18362
Intel Core i5-8250U örgjörvi 1.60GHz (Kaby Lake R), 1 örgjörvi, 8 rökfræðilegir og 4 líkamlegir kjarna
.NET Core SDK=3.0.100
[Gestgjafi]: .NET Core 2.2.7 (CoreCLR 4.6.28008.02, CoreFX 4.6.28008.03), 64bita RyuJIT
Kjarni: .NET Core 2.2.7 (CoreCLR 4.6.28008.02, CoreFX 4.6.28008.03), 64bita RyuJIT
[Gestgjafi]: .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64bita RyuJIT
Kjarni: .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64bita RyuJIT

Starf=Kjarni Runtime=Kjarni

ToList vs ToArray og Cycles


Ég ætlaði að undirbúa þessar upplýsingar með útgáfu .NET Core 3.0, en þeir unnu mig, ég vil ekki stela dýrð einhvers annars og afrita upplýsingar annarra, svo ég bendi bara á hlekkur á góða grein þar sem samanburðinum er lýst ítarlega.

Fyrir mína hönd vil ég bara kynna fyrir þér mælingar mínar og niðurstöður; ég bætti öfugum lykkjum við þær fyrir unnendur „C++ stílsins“ að skrifa lykkjur.

code:

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

Frammistöðuhraði í .NET Core 2.2 og 3.0 er nánast sá sami. Hér er það sem ég gat fengið í .NET Core 3.0:

Afköst í .NET Core

Afköst í .NET Core

Við getum ályktað að ítrekuð vinnsla á Array safni sé hraðari vegna innri hagræðingar þess og skýrrar úthlutunar safnstærðar. Það er líka þess virði að muna að Listasafn hefur sína eigin kosti og þú ættir að nota rétt safn eftir útreikningum sem krafist er. Jafnvel ef þú skrifar rökfræði til að vinna með lykkjur, ekki gleyma því að þetta er venjuleg lykkja og hún er einnig háð mögulegri lykkjuhagræðingu. Grein var birt á habr fyrir nokkuð löngu síðan: https://habr.com/ru/post/124910/. Það er enn viðeigandi og mælt með lestri.

Kasta

Fyrir ári síðan vann ég hjá fyrirtæki við arfleifð verkefni, í því verkefni var eðlilegt að vinna úr vettvangsprófun í gegnum tilraunaupptöku. Ég skildi þá þegar að þetta var óheilbrigð viðskiptarökfræði fyrir verkefnið, svo þegar það var hægt reyndi ég að nota ekki slíka hönnun. En við skulum reikna út hvers vegna aðferðin við að meðhöndla villur með slíkri byggingu er slæm. Ég skrifaði lítinn kóða til að bera saman aðferðirnar tvær og gerði viðmið fyrir hvern valmöguleika.

code:

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

Niðurstöðurnar í .NET Core 3.0 og Core 2.2 hafa svipaða niðurstöðu (.NET Core 3.0):

Afköst í .NET Core

Afköst í .NET Core

Try catch gerir kóðann erfiðari að skilja og eykur framkvæmdartíma forritsins. En ef þú þarft þessa smíði, ættir þú ekki að setja inn þessar línur af kóða sem ekki er búist við að muni höndla villur - þetta mun gera kóðann auðveldari að skilja. Reyndar er það ekki svo mikið meðhöndlun undantekninga sem hleður kerfinu, heldur frekar að henda villunum sjálfum í gegnum kasta nýja undantekningarsmíðið.

Að henda undantekningum er hægara en einhver flokkur sem mun safna villunni á tilskildu sniði. Ef þú ert að vinna úr eyðublaði eða einhverjum gögnum og þú veist greinilega hver villan ætti að vera, hvers vegna ekki að vinna úr þeim?

Þú ættir ekki að skrifa throw new Exception() smíði ef þetta ástand er ekki óvenjulegt. Að meðhöndla og henda undantekningu er mjög dýrt!!!

ToLower, ToLowerInvariant, ToUpper, ToUpperInvariant

Á 5 ára reynslu minni við að vinna á .NET pallinum hef ég rekist á mörg verkefni sem notuðu strengjasamsvörun. Ég sá líka eftirfarandi mynd: það var ein Enterprise lausn með mörgum verkefnum, sem hvert um sig gerði strengjasamanburð á annan hátt. En hvað ætti að nota og hvernig á að sameina það? Í bókinni CLR via C# eftir Richter las ég upplýsingar um að ToUpperInvariant() aðferðin sé hraðari en ToLowerInvariant().

Brot úr bókinni:

Afköst í .NET Core

Auðvitað trúði ég því ekki og ákvað að keyra nokkur próf þá á .NET Framework og niðurstaðan hneykslaði mig - meira en 15% frammistöðuaukning. Svo þegar ég kom í vinnuna morguninn eftir sýndi ég yfirmönnum mínum þessar mælingar og gaf þeim aðgang að frumkóðanum. Eftir þetta var 2 af 14 verkefnum breytt til að koma til móts við nýju mælingarnar og miðað við að þessi tvö verkefni voru til við að vinna risastórar Excel töflur var útkoman meira en marktæk fyrir vöruna.

Ég kynni einnig fyrir þér mælingar fyrir mismunandi útgáfur af .NET Core, svo að hver og einn geti valið um bestu lausnina. Og ég vil bara bæta því við að í fyrirtækinu þar sem ég vinn notum við ToUpper() til að bera saman strengi.

code:

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

Afköst í .NET Core

Afköst í .NET Core

Í .NET Core 3.0 er aukningin fyrir hverja þessara aðferða ~x2 og jafnar útfærslurnar innbyrðis.

Afköst í .NET Core

Afköst í .NET Core

Tier samantekt

Í síðustu grein minni lýsti ég þessari virkni stuttlega, mig langar að leiðrétta og bæta við orð mín. Fjölþrepa samantekt flýtir fyrir ræsingartíma lausnarinnar þinnar, en þú fórnar því að hlutar kóðans þíns verði settir saman í fínstilltari útgáfu í bakgrunni, sem getur kynnt smá kostnaður. Með tilkomu NET Core 3.0 hefur byggingatími fyrir verkefni með flokkasamsetningu virkjað minnkað og villur tengdar þessari tækni hafa verið lagaðar. Áður leiddi þessi tækni til villna í fyrstu beiðnum í ASP.NET Core og frýs við fyrstu byggingu í fjölþrepa safnstillingu. Það er nú sjálfgefið virkt í .NET Core 3.0, en þú getur slökkt á því ef þú vilt. Ef þú ert í stöðu teymisstjóra, yfirmanns, miðjumanns, eða þú ert deildarstjóri, þá verður þú að skilja að hröð verkefnaþróun eykur verðmæti teymisins og þessi tækni gerir þér kleift að spara tíma fyrir báða þróunaraðila og tíma verkefnisins sjálfs.

.NET stig upp

Uppfærðu .NET Framework / .NET Core útgáfuna þína. Oft veitir hver ný útgáfa aukinn árangur og bætir við nýjum eiginleikum.

En hverjir eru nákvæmlega kostir þess? Við skulum skoða nokkrar þeirra:

  • .NET Core 3.0 kynnti R2R myndir sem munu draga úr ræsingartíma .NET Core forrita.
  • Með útgáfu 2.2 birtist Tier Compilation, þökk sé því sem forritarar munu eyða minni tíma í að hefja verkefni.
  • Stuðningur við nýja .NET staðla.
  • Stuðningur við nýja útgáfu af forritunarmálinu.
  • Hagræðing, með hverri nýrri útgáfu batnar hagræðing grunnsafnanna Collection/Struct/Stream/String/Regex og margt fleira. Ef þú ert að flytja úr .NET Framework yfir í .NET Core færðu mikla frammistöðuaukningu úr kassanum. Sem dæmi læt ég fylgja með tengil á nokkrar af þeim fínstillingum sem bætt var við .NET Core 3.0: https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-core-3-0/

Afköst í .NET Core

Ályktun

Þegar þú skrifar kóða er þess virði að gefa gaum að mismunandi þáttum verkefnisins og nota eiginleika forritunarmálsins og vettvangsins til að ná sem bestum árangri. Mér þætti vænt um ef þú deilir þekkingu þinni varðandi hagræðingu í .NET.

Tengill á github

Heimild: www.habr.com

Bæta við athugasemd