Denne artikel er en spejling af maskinoversættelse, klik venligst her for at springe til den oprindelige artikel.

Udsigt: 6846|Svar: 2

[Kilde] [Drej]. .NET Performance Optimization - Collections.Pooled anbefales

[Kopier link]
Opslået den 29-5-2022 kl. 13:45:22 | | | |
Kort introduktion

Ydelsesoptimering handler om, hvordan man sikrer, at det samme antal forespørgsler behandles med færre ressourcer, som generelt er CPU eller hukommelse, og selvfølgelig operativsystemets IO-håndtering, netværkstrafik, diskforbrug osv. Men det meste af tiden reducerer vi CPU- og hukommelsesforbruget.
Det tidligere delte indhold har nogle begrænsninger, det er svært at transformere direkte, i dag vil jeg dele en simpel metode med dig: du behøver kun udskifte nogle få samlingstyper for at opnå effekten af forbedret ydeevne og mindske hukommelsesforbruget.
I dag vil jeg dele et klassebibliotek med jer, detteKlassens bibliotek hedder Collections. Pooled, Som navnet kan se, er det gennem pooled memory for at opnå formålet at reducere hukommelsesaftryk og GC, og vi vil direkte se, hvordan ydeevnen er, og vi vil også tage dig med til kildekoden, hvorfor den giver disse ydelsesforbedringer.

Samlinger. Sammenlagt

Projektlink:Hyperlink-login er synlig.

Biblioteket er baseret på klasser i System.Collections.Generic, som er blevet modificeret for at udnytte de nye System.Span <T>og System.Buffers.ArrayPool <T>klassebiblioteker med det formål at reducere hukommelsesallokering, forbedre ydeevnen og muliggøre større interoperabilitet med moderne API'er.
Collections.Pooled understøtter .NET Standnd 2.0 (.NET Framework 4.6.1+), samt understøttelse af . NET Core 2.1+. Et omfattende sæt enhedstests og benchmarks er blevet portet fra CoreFX.

Samlet antal tests: 27.501. Via: 27501. Fejl: 0. Spring: 0.
Testkørslen var vellykket.
Testudførelsestid: 9,9019 sekunder

Sådan bruger du

Du kan nemt installere dette bibliotek via Nuget, NuGet Version.

I Collections.Pooled-biblioteket implementerer den poolede versioner for de samlingstyper, vi almindeligvis bruger, som vist i sammenligningen med .NETs native typer.

. .NET nativeSamlinger. Sammenlagtbemærkning
Liste<T>PooledList<T>Generiske samlingsklasser
Dictionary<TKey, TValue>PooledDictionary<TKey, TValue>Generisk ordbogsklasse
HashSet<T>PooledSet<T>Generiske hash-samlingsklasser
Stak<T>Stak<T>Generiske stakke
Kø<T>PooledQueue<T>Generisk kohorte

Når vi bruger, behøver vi kun at tilføje den tilsvarende . .NET native version med Collections.Pooled-versionen, som vist i koden nedenfor:

Vi skal dog bemærke, at Pooled-typen implementerer IDispose-interfacet, som returnerer den brugte hukommelse til poolen via Dispose()-metoden, så vi skal kalde dens Dispose()-metode efter at have brugt Pooled collection-objektet. Eller du kan bruge nøgleordet using var direkte.

Bemærk: Brug samlingsobjektet inde i Collections.PooledDet er bedst at skulle frigive den manuelt, men det er ligegyldigt, om du ikke frigiver den, GC vil til sidst genanvende den, men den kan ikke returneres til poolen, og den vil ikke opnå effekten af at gemme hukommelse.
Da den genbruger hukommelsesplads, skal den, når den returnerer hukommelsespladsen til poolen, behandle elementerne i samlingen, og den leverer en oplistning kaldet ClearMode til brug, defineret som følger:




Som standard kan du bruge standardværdien Auto, og hvis der er særlige ydelseskrav, kan du bruge Never efter at have kendt risiciene.
For referencetyper og værdityper, der indeholder referencetyper, skal vi tømme array-referencen, når hukommelsespladsen returneres til poolen; hvis den ikke er ryddet, vil GC ikke kunne frigøre denne del af hukommelsespladsen (fordi elementets reference altid har været holdt af poolen). Hvis det er en ren værditype, kan den ikke tømmes. I denne artikel beskriver jeg forskellen i lagring mellem referencetyper og struct (værditype) arrays, rene værdityper har ikke objektheader-genbrug og kræver ikke GC-indgriben.


. .NET Performance Optimization - Brug struktur-alternative klasser:Hyperlink-login er synlig.

Ydelsessammenligning

Jeg lavede ikke kun Benchmark, og de løbende scoreresultater for open source-projekter, som jeg brugte direkte, var 0 for hukommelsesforbruget i mange projekter, hvilket skyldtes, at den samlede hukommelse ikke havde nogen ekstra allokering.

PooledList<T>

Loop gennem de 2048-elementer, der er tilføjet til sættet i Benchmark, . .NET native List <T>kræver 110us (ifølge de faktiske benchmarkresultater burde millisekunderne i figuren være en administrativ fejl) og 263KB hukommelse, mens PooledList <T>kun behøver 36us og 0KB hukommelse.




PooledDictionary<TKey, TValue>

Tilføj 10_0000 elementer til ordbogen i en løkke i Benchmark, . .NET native Dictionary<TKey, TValue> kræver 11 ms og 13 MB hukommelse, mens PooledDictionary<TKey, TValue> kun kræver 7 ms og 0 MB hukommelse.




PooledSet<T>

Loop gennem hash-samlingen i Benchmark og tilføj 10_0000 elementer, . .NET's native HashSet <T>kræver 5348 ms og 2 MB, mens PooledSet <T>kun kræver 4723 ms og 0 MB hukommelse.




PooledStack<T>

Loop gennem stakken i Benchmark for at tilføje 10_0000 elementer, . .NET-native PooledStack <T>kræver 1079 ms og 2 MB, mens PooledStack <T>kun kræver 633 ms og 0 MB hukommelse.




PooledQueue<T>

Loop gennem løkkerne i Benchmark for at tilføje 10_0000 elementer til køen, . .NETs native <T>PooledQueue kræver 681 ms og 1 MB, mens PooledQueue <T>kun kræver 408 ms og 0 MB hukommelse.




Scenen frigives ikke manuelt

Derudover nævnte vi ovenfor, at den samlede samlingstype skal frigives, men det er ligegyldigt, om den ikke bliver frigivet, fordi GC vil genbruge.


Benchmark-resultaterne er som følger:



Konklusionen kan drages ud fra benchmarkresultaterne ovenfor.

At frigive den samlede typesamling i tide udløser knap nok GC og allokerer hukommelse; ifølge ovenstående graf allokerer den kun 56 byte hukommelse.
Selv hvis Pooled-typesamlingen ikke frigives, vil den stadig genbruge hukommelse under ReSize-udvidelsesoperationen og springe GC-allokeringshukommelsesinitialiseringen over, som er relativt hurtig.
Den langsomste er at bruge den normale samlingstype, hver ReSize-udvidelsesoperation skal anvendes for ny hukommelsesplads, og GC skal også genvinde den tidligere hukommelsesplads.


Principanalyse

Hvis du har læst mit tidligere blogindlæg, bør du sætte den indledende størrelse for samlingstyper og analysere implementeringsprincippet for C# Dictionary, du kan vide, at .NET BCL-udviklere bruger de underliggende datastrukturer for disse grundlæggende samlingstyper som arrays for højtydende random access, lad os tage List <T>som eksempel.

Opret et nyt array til at gemme de tilføjede elementer.
Hvis der ikke er nok plads i arrayet, udløses udvidelsesoperationen til at anmode om dobbelt så stor pladsstørrelse.
Konstruktørkoden er som følger, og du kan se, at det er et generisk array, der er oprettet direkte:


Så hvis du vil poole hukommelsen, skal du kun ændre stedet, hvor det nye nøgleordsprogram bruges i klassebiblioteket, for at bruge pooled application. Her deler jeg det med dig. NET BCL er en type kaldet ArrayPool, som leverer en array-ressourcepulje af genanvendelige generiske instanser, der kan bruges til at reducere presset på GC og forbedre ydeevnen i tilfælde af hyppig oprettelse og destruktion af arrays.

Det underliggende lag af vores Pooled-type er at bruge ArrayPool til at dele ressourcepuljer, og ud fra dens konstruktør kan vi se, at den bruger ArrayPool som standard<T>. Delt for at tildele array-objekter, og selvfølgelig kan du også oprette din egen ArrayPool til at bruge det.


Derudover returneres det gamle array til trådpuljen, når man udfører en kapacitetsjusteringsoperation (udvidelse), og det nye array erhverves også fra puljen.

Derudover bruger forfatteren Span til at optimere API'er som Add og Insert for at give dem bedre ydeevne ved tilfældig adgang. Derudover er TryXXX-seriens API blevet tilføjet, så du kan bruge den på en mere bekvem måde. For eksempel <T>har List-klassen <T>op til 170 ændringer sammenlignet med PooledList.



resumé

I vores faktiske onlinebrug kan vi erstatte den native samlingstype med den samlingstype, som Pooled leverer, hvilket er meget hjælpsomt til at reducere hukommelsesforbrug og P95-latens.
Selv hvis du glemmer at frigive den, vil ydeevnen ikke være meget dårligere end at bruge den native samlingstype. Selvfølgelig er den bedste vane at slippe det ud i tide.


Oprindelig:Hyperlink-login er synlig.




Tidligere:RecyclableMemoryStream leverer højtydende .NET-streaming
Næste:[Praktisk kamp] Serveren bygger LibreSpeed for at teste netværkshastigheden
Opslået den 29-5-2022 kl. 17:12:36 |
Lær det
Opslået den 20-6-2022 09:09:22 |
Lær mixet
Ansvarsfraskrivelse:
Al software, programmeringsmaterialer eller artikler udgivet af Code Farmer Network er kun til lærings- og forskningsformål; Ovenstående indhold må ikke bruges til kommercielle eller ulovlige formål, ellers skal brugerne bære alle konsekvenser. Oplysningerne på dette site kommer fra internettet, og ophavsretstvister har intet med dette site at gøre. Du skal slette ovenstående indhold fuldstændigt fra din computer inden for 24 timer efter download. Hvis du kan lide programmet, så understøt venligst ægte software, køb registrering og få bedre ægte tjenester. Hvis der er nogen overtrædelse, bedes du kontakte os via e-mail.

Mail To:help@itsvse.com