Denne artikkelen er en speilartikkel om maskinoversettelse, vennligst klikk her for å hoppe til originalartikkelen.

Utsikt: 6846|Svare: 2

[Kilde] [Snu]. .NET ytelsesoptimalisering - Collections.Pooled anbefales

[Kopier lenke]
Publisert 29.05.2022 13:45:22 | | | |
Kort introduksjon

Ytelsesoptimalisering er hvordan man sikrer at samme antall forespørsler behandles med færre ressurser, som vanligvis er CPU eller minne, og selvfølgelig operativsystemets IO-håndter, nettverkstrafikk, diskbruk osv. Men for det meste reduserer vi CPU- og minnebruket.
Innholdet som ble delt tidligere har noen begrensninger, det er vanskelig å transformere direkte, i dag vil jeg dele en enkel metode med dere, det er bare behov for å erstatte noen få samlingstyper for å oppnå effekten av å forbedre ytelsen og redusere minneavtrykket.
I dag vil jeg dele med dere et klassebibliotek, detteKlassebiblioteket heter Collections.Pooled, Som navnet kan se, er det gjennom pooled memory for å oppnå formålet å redusere minneavtrykket og GC, og vi vil direkte se hvordan ytelsen er, og vi vil også ta deg med for å se kildekoden, hvorfor det gir disse ytelsesforbedringene.

Samlinger. Samlet

Prosjektlenke:Innloggingen med hyperkoblingen er synlig.

Biblioteket er basert på klasser i System.Collections.Generic, som har blitt modifisert for å dra nytte av de nye System.Span- <T>og System.Buffers.ArrayPool-klassebibliotekene <T>for å redusere minneallokering, forbedre ytelsen og tillate større interoperabilitet med moderne API-er.
Collections.Pooled støtter .NET Stand 2.0 (.NET Framework 4.6.1+), samt støtte for . NET Core 2.1+. Et omfattende sett med enhetstester og benchmarktester er portert fra CoreFX.

Totalt antall tester: 27 501. Via: 27501. Feil: 0. Hopp over: 0.
Testkjøringen var vellykket.
Testutførelsestid: 9,9019 sekunder

Hvordan bruke

Du kan enkelt installere dette biblioteket gjennom Nuget, NuGet Version.

I Collections.Pooled-biblioteket implementerer det poolede versjoner for de samlingstypene vi vanligvis bruker, som vist i sammenligningen med .NETs native typer.

. .NET nativeSamlinger. Samletbemerkning
Liste<T>PooledList<T>Generiske samlingsklasser
Dictionary<TKey, TValue>PooledDictionary<TKey, TValue>Generisk ordbokklasse
HashSet<T>PooledSet<T>Generiske hash-samlingsklasser
Stabel<T>Stabel<T>Generiske stakker
Kø<T>PooledQueue<T>Generisk kohort

Når vi bruker, trenger vi bare å legge til den tilsvarende . .NET native versjon med Collections.Pooled-versjonen, som vist i koden nedenfor:

Vi må imidlertid merke oss at Pooled-typen implementerer IDispose-grensesnittet, som returnerer det brukte minnet til poolen via Dispose()-metoden, så vi må kalle Dispose()-metoden etter å ha brukt Pooled collection-objektet. Eller du kan bruke nøkkelordet using var direkte.

Merk: Bruk samlingsobjektet inne i Collections.PooledDet er best å måtte slippe den manuelt, men det spiller ingen rolle om du ikke slipper den, GC vil til slutt resirkulere den, men den kan ikke returneres til poolen, og den vil ikke oppnå effekten av å spare minne.
Siden den gjenbruker minneplass, må den behandle elementene i samlingen når den returnerer minneplass, og den gir en enumerasjon kalt ClearMode for bruk, definert som følger:




Som standard kan du bruke standardverdien Auto, og hvis det er spesielle ytelseskrav, kan du bruke Never etter å ha kjent risikoene.
For referansetyper og verdityper som inneholder referansetyper, må vi tømme array-referansen når vi returnerer minneplassen til poolen; hvis den ikke er slettet, vil ikke GC kunne frigjøre denne delen av minneplassen (fordi referansen til elementet alltid har vært holdt av poolen), hvis det er en ren verditype, kan den ikke tømmes. I denne artikkelen beskriver jeg lagringsforskjellen mellom referansetyper og struct (verditype) arrays, rene verdityper har ikke gjenbruk av objektoverskrifter og krever ikke GC-inngripen.


. .NET ytelsesoptimalisering - Bruk strukturalternativklasser:Innloggingen med hyperkoblingen er synlig.

Ytelsessammenligning

Jeg gjorde ikke Benchmark alene, og de løpende poengresultatene for åpne kildekode-prosjekter jeg brukte direkte var 0 for minnebruken til mange prosjekter, noe som var fordi det samlede minnet som ble brukt ikke hadde noen ekstra allokering.

PooledList<T>

Loop gjennom 2048-elementene lagt til settet i Benchmark, . .NETs native List <T>krever 110us (ifølge de faktiske benchmark-resultatene skal millisekundene i figuren være en skrivefeil) og 263KB minne, mens PooledList <T>kun trenger 36us og 0KB minne.




PooledDictionary<TKey, TValue>

Legg til 10_0000 elementer i ordboken i en løkke i Benchmark, . .NET native Dictionary<TKey, TValue> krever 11 ms og 13 MB minne, mens PooledDictionary<TKey, TValue> bare krever 7 ms og 0 MB minne.




PooledSet<T>

Loop gjennom hash-samlingen i Benchmark legg til 10_0000 elementer, . .NETs native HashSet <T>krever 5348 ms og 2 MB, mens PooledSet <T>kun krever 4723 ms og 0 MB minne.




PooledStack<T>

Gå gjennom stakken i Benchmark for å legge til 10_0000 elementer, . .NET-native PooledStack <T>krever 1079 ms og 2 MB, mens PooledStack <T>kun krever 633 ms og 0 MB minne.




PooledQueue<T>

Gå gjennom løkkene i Benchmark for å legge til 10_0000 elementer i køen, . .NETs native <T>PooledQueue krever 681 ms og 1 MB, mens PooledQueue <T>kun krever 408 ms og 0 MB minne.




Scenen slippes ikke manuelt

I tillegg nevnte vi ovenfor at typen pooled collection må frigis, men det spiller ingen rolle om den ikke blir utlevert, fordi GC vil resirkulere.


Benchmark-resultatene er som følger:



Konklusjonen kan trekkes fra benchmark-resultatene ovenfor.

Å slippe Pooled-typesamlingen i tid utløser knapt GC og allokerer minne, fra grafen over allokerer den bare 56 byte minne.
Selv om Pooled-typesamlingen ikke blir frigitt, vil den fortsatt gjenbruke minne under ReSize-utvidelsesoperasjonen fordi den allokerer minne fra poolen, og hoppe over GC-allokeringsminneinitialiseringssteget, som er relativt raskt.
Den tregeste er å bruke normal samlingstype, hver ReSize-utvidelsesoperasjon må brukes for nytt minneplass, og GC må også gjenerobre det forrige minneområdet.


Prinsippanalyse

Hvis du har lest mitt forrige blogginnlegg, bør du sette startstørrelsen for samlingstyper og analysere implementeringsprinsippet for C# Dictionary, du kan vite at .NET BCL-utviklere bruker de underliggende datastrukturene til disse grunnleggende samlingstypene som arrays for høyytelses tilfeldig tilgang, la oss ta List <T>som et eksempel.

Lag et nytt array for å lagre de ekstra elementene.
Hvis det ikke er nok plass i arrayet, utløses utvidelsesoperasjonen for å be om dobbelt så stor plassstørrelse.
Konstruktørkoden er som følger, og du kan se at det er et generisk array som er laget direkte:


Så hvis du vil poole minne, trenger du bare å endre stedet hvor det nye nøkkelordprogrammet brukes i klassebiblioteket for å bruke pooled application. Her deler jeg den med deg. NET BCL er en type kalt ArrayPool, som gir en ressurspool for gjenbrukbare generiske instanser, som kan brukes til å redusere presset på GC og forbedre ytelsen ved hyppig opprettelse og ødeleggelse av arrays.

Det underliggende laget i vår Pooled-type er å bruke ArrayPool for å dele ressurspooler, og fra konstruktøren kan vi se at den bruker ArrayPool som standard<T>. Delt for å tildele array-objekter, og selvfølgelig kan du også lage din egen ArrayPool for å bruke den.


I tillegg, når man utfører en kapasitetsjusteringsoperasjon (utvidelse), returneres det gamle arrayet til trådpoolen, og det nye arrayet hentes også fra poolen.

I tillegg bruker forfatteren Span for å optimalisere API-er som Add og Insert for å gi bedre ytelse ved tilfeldig tilgang. I tillegg er TryXXX-seriens API lagt til, slik at du kan bruke det på en mer praktisk måte. For eksempel <T>har List-klassen <T>opptil 170 modifikasjoner sammenlignet med PooledList.



sammendrag

I vår faktiske online bruk kan vi erstatte den native samlingstypen med samlingstypen som tilbys av Pooled, noe som er svært nyttig for å redusere minnebruk og P95-forsinkelse.
Også, selv om du glemmer å slippe den, vil ikke ytelsen være mye dårligere enn å bruke den opprinnelige samlingstypen. Selvfølgelig er den beste vanen å slippe det ut i tide.


Original:Innloggingen med hyperkoblingen er synlig.




Foregående:RecyclableMemoryStream tilbyr høyytelses .NET-strømming
Neste:[Praktisk kamp] Serveren bygger LibreSpeed for å teste nettverkshastigheten
Publisert 29.05.2022 kl. 17:12:36 |
Lær det
Publisert 2022-06-20 09:09:22 |
Lær deg miksen
Ansvarsfraskrivelse:
All programvare, programmeringsmateriell eller artikler publisert av Code Farmer Network er kun for lærings- og forskningsformål; Innholdet ovenfor skal ikke brukes til kommersielle eller ulovlige formål, ellers skal brukerne bære alle konsekvenser. Informasjonen på dette nettstedet kommer fra Internett, og opphavsrettstvister har ingenting med dette nettstedet å gjøre. Du må fullstendig slette innholdet ovenfor fra datamaskinen din innen 24 timer etter nedlasting. Hvis du liker programmet, vennligst støtt ekte programvare, kjøp registrering, og få bedre ekte tjenester. Hvis det foreligger noen krenkelse, vennligst kontakt oss på e-post.

Mail To:help@itsvse.com