Vra

Ons het 'n paar operasies waar ons 'n groot aantal groot string-aaneenskakelings doen, en het onlangs 'n uitsondering uit die geheue teëgekom.Ongelukkig is ontfouting van die kode nie 'n opsie nie, aangesien dit by 'n klantwebwerf plaasvind.

Dus, voordat ek na 'n hersiening van ons kode kyk, wil ek vra:wat is die RAM-verbruikseienskappe van StringBuilder vir groot snare?

Veral as hulle vergelyk met die standaard string tipe.Die grootte van die stringe is meer as 10 MB, en dit lyk asof ons die probleme rondom 20 MB raakloop.

LET WEL:Dit gaan nie oor spoed nie, maar oor RAM.

Was dit nuttig?

Oplossing

Hier is 'n mooi studie oor String aaneenskakeling vs geheue toewysing.

As jy aaneenskakeling kan vermy, doen dit!

Dit is 'n no brainer, as u nie hoef saam te voeg nie, maar wil hê dat u bronkode mooi moet lyk, gebruik die eerste metode.Dit sal geoptimaliseer word asof dit 'n enkele string is.

Moet nooit += aaneenskakeling gebruik nie. Te veel veranderinge vind plaas agter die toneel, wat in die eerste plek nie duidelik uit my kode is nie.Ek raai u aan om eerder String.concat () eksplisiet te gebruik met enige oorbelasting (2 snare, 3 snare, string skikking).Dit sal duidelik wys wat u kode doen sonder enige verrassings, terwyl u uself toelaat om die doeltreffendheid te ondersoek.

Probeer om die teikengrootte van 'n StringBuilder te skat.

Hoe meer akkuraat u die nodige grootte kan skat, hoe minder tydelike snare sal die StringBuilder moet skep om sy interne buffer te verhoog.

Moenie enige Format()-metodes gebruik wanneer prestasie 'n probleem is nie.

Te veel bokant is betrokke by die ontleding van die formaat, wanneer u 'n skikking uit stukke kon bou wanneer al wat u gebruik {x} vervang.Formaat () is goed vir leesbaarheid, maar een van die dinge wat u moet doen as u alle moontlike prestasies uit u toepassing druk.

Ander wenke

Elke keer as StringBuilder nie meer spasie het nie, hertoeken dit 'n nuwe buffer twee keer die grootte van die oorspronklike buffer, kopieer die ou karakters en laat die ou buffer GC'd kry.Dit is moontlik dat jy net genoeg gebruik (noem dit x) sodat 2x groter is as die geheue wat jy mag toeken.Jy sal dalk 'n maksimum lengte vir jou snare wil bepaal, en dit aan die bouer van StringBuilder deurgee sodat jy vooraf toeken, en jy is nie oorgelewer aan die verdubbeling hertoewysing nie.

Jy sal dalk belangstel deur die toue-datastruktuur.Hierdie artikel: Toue:Teorie en praktyk verduidelik hul voordele.Miskien is daar 'n implementering vir .NET.

Opdatering, om die opmerking te beantwoord] Gebruik dit minder geheue?Soek geheue in die artikel, sal jy 'n paar wenke vind.
Basies, ja, ten spyte van die struktuur bokoste, want dit voeg net geheue by wanneer dit nodig is.StringBuilder, wanneer ou buffer uitgeput word, moet 'n baie groter een toewys (wat reeds leë geheue kan mors) en laat die ou een los (wat as vullis versamel sal word, maar nog steeds baie geheue kan gebruik intussen).

Ek het nie 'n implementering vir .NET gevind nie, maar daar is ten minste 'n C++ implementering (in SGI se STL: http://www.sgi.com/tech/stl/Rope.html).Miskien kan jy hierdie implementering benut.Let op die bladsy waarna ek verwys het 'n werk oor geheue prestasie.

Let daarop dat toue nie die genesing vir alle probleme is nie:hul bruikbaarheid hang baie af hoe jy jou groot snare bou en hoe jy dit gebruik.Die artikels wys op voordele en nadele.

Strigbuilder is 'n uitstekende oplossing vir geheueprobleme wat veroorsaak word deur aaneenlopende snare.

Om jou spesifieke vraag te beantwoord, Stringbuilder het 'n konstante-grootte bokoste in vergelyking met 'n normale string waar die lengte van die string gelyk is aan die lengte van die tans-toegekende Stringbuilder buffer.Die buffer kan moontlik twee keer so groot wees as die string wat ontstaan, maar geen geheuetoewysings sal meer gemaak word wanneer dit aan die Stringbuilder gekoppel word totdat die buffer gevul is nie, so dit is regtig 'n uitstekende oplossing.

In vergelyking met tou, is dit uitstaande.

string output = "Test";
output += ", printed on " + datePrinted.ToString();
output += ", verified by " + verificationName;
output += ", number lines: " + numberLines.ToString();

Hierdie kode het vier stringe wat as letterlik in die kode gestoor word, twee wat in die metodes geskep word en een uit 'n veranderlike, maar dit gebruik ses afsonderlike intermediêre stringe wat langer en langer word.As hierdie patroon voortgesit word, sal dit geheuegebruik teen 'n eksponensiële tempo verhoog totdat die GC inskop om dit skoon te maak.

Ek weet nie van die presiese geheuepatroon van snaarbouer nie, maar die algemene snaar is nie 'n opsie nie.

Wanneer jy die gewone string gebruik, skep elke aaneenskakeling nog 'n paar snaarvoorwerpe, en die geheueverbruik het die hoogte ingeskiet, wat die vullisverwyderaar te gereeld laat roep.

string a = "a";

//creates object with a

a += "b"

/creates object with b, creates object with ab, assings object with ab to "a" pointer
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top