Ta članek je zrcalni članek strojnega prevajanja, kliknite tukaj za skok na izvirni članek.

Pogled: 6846|Odgovoriti: 2

[Vir] [Obrat]. .NET optimizacija zmogljivosti - Collections.Pooled je priporočljiv

[Kopiraj povezavo]
Objavljeno 29. 5. 2022 ob 13:45:22 | | | |
Kratek uvod

Optimizacija zmogljivosti je način, kako zagotoviti, da se enako število zahtevkov obdela z manj viri, ki so običajno procesor ali pomnilnik, in seveda operacijski vhodni sistemi, omrežni promet, porabo diska itd. Večino časa pa zmanjšujemo porabo procesorja in pomnilnika.
Vsebina, ki je bila prej deljena, ima nekatere omejitve, težko jo je neposredno transformirati, danes pa vam želim predstaviti preprosto metodo: zamenjati je treba le nekaj vrst zbirk, da dosežemo učinek izboljšanja zmogljivosti in zmanjšanja pomnilniške odtise.
Danes vam želim predstaviti razredno knjižnico, toRazredna knjižnica se imenuje Collections.Pooled, Kot je razvidno iz imena, gre za uporabo združenega pomnilnika, da se doseže namen zmanjšanja pomnilniške porabe in GC, neposredno pa bomo videli, kakšna je njegova zmogljivost, prav tako pa vas bomo popeljali k izvorni kodi, zakaj prinaša te izboljšave zmogljivosti.

Zbirke. Združene

Povezava do projekta:Prijava do hiperpovezave je vidna.

Knjižnica temelji na razredih v System.Collections.Generic, ki so bili prilagojeni, da izkoristijo nove <T>knjižnice razredov System.Span in System.Buffers.ArrayPool <T>z namenom zmanjšanja dodeljevanja pomnilnika, izboljšanja zmogljivosti in omogočanja večje interoperabilnosti z modernimi API-ji.
Collections.Pooled podpira .NET Standnd 2.0 (.NET Framework 4.6.1+) ter podpira . NET Core 2.1+. Obsežen nabor enotskih testov in primerjalnih testov je bil prenesen iz CoreFX.

Skupno število testov: 27.501. Vir: 27501. Neuspeh: 0. Preskok: 0.
Preizkus je bil uspešen.
Čas izvajanja testa: 9,9019 sekund

Kako uporabljati

To knjižnico lahko enostavno namestite preko Nuget, NuGet Version.

V knjižnici Collections.Pooled implementira združene različice za vrste zbirk, ki jih običajno uporabljamo, kot je prikazano v primerjavi z nativnimi .NET tipi.

. .NET nativeZbirke. ZdruženePripombo
Seznam<T>Združeni seznam<T>Generični razredi zbirk
Slovar<TKey, TValue>PooledDictionary<TKey, TValue>Razred generičnih slovarjev
HashSet<T>Združena zbirka<T>Generični razredi zbirke zgoščenih točk
Stack<T>Stack<T>Generični skladi
Vrsta<T>PooledQueue<T>Generična kohorta

Pri uporabi moramo le dodati ustrezni . .NET izvorna različica z različico Collections.Pooled, kot je prikazano v spodnji kodi:

Vendar pa moramo opozoriti, da tip Pooled implementira vmesnik IDispose, ki vrne uporabljeni pomnilnik v sklad preko metode Dispose(), zato moramo po uporabi objekta Pooled klicati metodo Dispose(). Lahko pa uporabite ključno besedo using var neposredno.

Opomba: Uporabite objekt zbirke znotraj Collections.PooledNajbolje je, da ga sprostite ročno, vendar ni pomembno, če ga ne sprostite, GC ga bo sčasoma recikliral, vendar ga ni mogoče vrniti v bazen in ne bo dosegel učinka varčevanja pomnilnika.
Ker ponovno uporablja pomnilniški prostor, mora ob vračanju pomnilniškega prostora v sklad obdelati elemente v zbirki in zagotavlja enumeracijo, imenovano ClearMode za uporabo, definirano takole:




Privzeto lahko uporabite privzeto vrednost Auto, če pa obstajajo posebne zahteve glede zmogljivosti, lahko uporabite Nikoli, ko poznate tveganja.
Za tipe referenc in vrednosti, ki vsebujejo reference tipe, moramo izprazniti referenco polja ob vračanju pomnilniškega prostora v sklad; če ni očiščena, GC ne bo mogel sprostiti tega dela pomnilniškega prostora (ker je referenca elementa vedno ostala v skladu (ker je referenca elementa vedno zadržana v bazenu), če gre za čisto vrednostno vrsto, je ni mogoče izprazniti; v tem članku opisujem razliko v shranjevanju med vrstami referenc in strukturnimi (vrednostnimi tipi); čisti vrednostni tipi nimajo recikliranja objektnih glav in ne potrebujejo GC intervencije.


. .NET optimizacija zmogljivosti - Uporaba alternativnih razredov strukture:Prijava do hiperpovezave je vidna.

Primerjava zmogljivosti

Benchmarka nisem delal sam, rezultati rezultatov odprtokodnih projektov, ki sem jih neposredno uporabljal, pa so bili 0 glede na porabo pomnilnika pri mnogih projektih, kar je bilo zato, ker skupni pomnilnik ni imel dodatne alokacije.

Združeni seznam<T>

Preglejte elemente iz leta 2048, dodane v zbirko v Benchmarku, . .NET native List <T>zahteva 110us (glede na dejanske rezultate testa naj bi milisekunde na sliki predstavljale administrativno napako) in 263KB pomnilnika, medtem ko PooledList <T>potrebuje le 36us in 0KB pomnilnika.




PooledDictionary<TKey, TValue>

Dodajte 10_0000 elementov v slovar v zanki v Benchmarku, . .NET izvorni slovar<TKey, TValue> zahteva 11ms in 13MB pomnilnika, medtem ko PooledDictionary<TKey, TValue> zahteva le 7ms in 0MB pomnilnika.




Združena zbirka<T>

Prehajaj skozi zbirko zgoščenj v Benchmarku in dodaj 10_0000 elementov, . Izvorni .NET HashSet <T>zahteva 5348ms in 2MB, medtem ko PooledSet <T>zahteva le 4723ms in 0MB pomnilnika.




PooledStack<T>

Zanko skozi sklad v Benchmarku dodate 10_0000 elementov. .NET nativni PooledStack <T>zahteva 1079ms in 2MB, medtem ko PooledStack <T>potrebuje le 633ms in 0MB pomnilnika.




PooledQueue<T>

Zanko skozi zanke v Benchmarku, da dodate 10_0000 elementov v čakalno vrsto, . .NET <T>nativni PooledQueue zahteva 681ms in 1MB, medtem ko PooledQueue <T>zahteva le 408ms in 0MB pomnilnika.




Prizor ni ročno sproščen

Poleg tega smo zgoraj omenili, da je treba tip združene zbirke sprostiti, vendar ni pomembno, če ni izdan, ker bo GC reciklirala.


Rezultati primerjalnih testov so naslednji:



Zaključek lahko potegnemo iz zgornjih rezultatov Benchmarka.

Pravočasno sprostitev zbirke tipov Pooled komaj sproži GC in dodeli pomnilnik, iz zgornjega grafa pa dodeli le 56 bajtov pomnilnika.
Tudi če zbirka tipov Pooled ni sproščena, ker dodeljuje pomnilnik iz sklada, bo še vedno ponovno uporabila pomnilnik med operacijo razširitve ReSize in preskočila korak inicializacije GC allocation pomnilnika, ki je razmeroma hiter.
Najpočasnejša je uporaba običajnega tipa zbirke, pri čemer mora vsaka operacija razširitve ReSize zahtevati nov pomnilniški prostor, GC pa mora ponovno pridobiti prejšnji pomnilniški prostor.


Glavna analiza

Če ste prebrali moj prejšnji blog zapis, bi morali nastaviti začetno velikost za vrste zbirk in analizirati implementacijski princip C# slovarja; veste lahko, da razvijalci .NET BCL uporabljajo osnovne podatkovne strukture teh osnovnih vrst zbirk kot polja za visoko zmogljiv naključni dostop, vzemimo za <T>primer List.

Ustvarite novo polje za shranjevanje dodanih elementov.
Če v polju ni dovolj prostora, se operacija razširitve sproži, da zahteva dvakratno velikost prostora.
Koda konstruktorja je naslednja in lahko vidite, da gre za generično polje, ustvarjeno neposredno:


Torej, če želite združiti pomnilnik, morate le spremeniti mesto, kjer se nova aplikacija za ključne besede uporablja v knjižnici razredov, da uporabite združeno aplikacijo. Tukaj ga delim z vami. NET BCL je tip, imenovan ArrayPool, ki zagotavlja bazen virov polja z ponovno uporabnimi generičnimi primerki, ki jih je mogoče uporabiti za zmanjšanje pritiska na GC in izboljšanje zmogljivosti v primeru pogostega ustvarjanja in uničenja polj.

Osnovna plast našega Pooled tipa je uporaba ArrayPoola za deljenje virov, in iz njegovega konstruktorja vidimo, da privzeto uporablja ArrayPool<T>. Delite za dodeljevanje objektov polj, seveda pa lahko ustvarite tudi svoj ArrayPool za uporabo.


Poleg tega se pri izvedbi operacije prilagajanja kapacitete (razširitve) stara polja vrnejo v bazen niti, nova polja pa se prav tako pridobijo iz sklada.

Poleg tega avtor uporablja Span za optimizacijo API-jev, kot sta Add in Insert, da jim omogoči boljšo zmogljivost naključnega dostopa. Poleg tega je bil dodan API serije TryXXX, tako da ga lahko uporabljate na bolj priročen način. Na primer, <T>razred List <T>ima do 170 sprememb v primerjavi s PooledList.



Povzetek

Pri naši dejanski spletni uporabi lahko izvorno vrsto zbirke zamenjamo s tipom zbirke, ki ga ponuja Pooled, kar je zelo koristno za zmanjšanje porabe pomnilnika in zakasnitve P95.
Prav tako, tudi če pozabiš izdati igro, zmogljivost ne bo veliko slabša kot pri uporabi izvorne zbirke. Seveda je najboljša navada, da jo pravočasno sprostiš.


Izvirno:Prijava do hiperpovezave je vidna.




Prejšnji:RecyclableMemoryStream zagotavlja visokozmogljivo .NET pretakanje
Naslednji:[Praktični boj] Strežnik zgradi LibreSpeed za testiranje hitrosti omrežja
Objavljeno 29. 5. 2022 ob 17:12:36 |
Nauči se
Objavljeno 2022-6-20 09:09:22 |
Naučite se mešanice
Disclaimer:
Vsa programska oprema, programski materiali ali članki, ki jih izdaja Code Farmer Network, so namenjeni zgolj učnim in raziskovalnim namenom; Zgornja vsebina ne sme biti uporabljena v komercialne ali nezakonite namene, sicer uporabniki nosijo vse posledice. Informacije na tej strani prihajajo z interneta, spori glede avtorskih pravic pa nimajo nobene zveze s to stranjo. Zgornjo vsebino morate popolnoma izbrisati z računalnika v 24 urah po prenosu. Če vam je program všeč, podprite pristno programsko opremo, kupite registracijo in pridobite boljše pristne storitve. Če pride do kakršne koli kršitve, nas prosimo kontaktirajte po elektronski pošti.

Mail To:help@itsvse.com