Quando ho un StringBuilder
vuoto con una capacità di 5 e scrivo "ciao, mondo!" ad esso, lo standard C# specifica la nuova capacità dello StringBuilder
? Ho una vaga memoria che è il doppio della lunghezza della nuova stringa (per evitare di cambiare la capacità con ogni nuova stringa aggiunta).Come cambia la capacità di StringBuilder?
risposta
Dipende dalla versione di .NET di cui si sta parlando. Prima di .NET 4, StringBuilder utilizzava lo standard .NET strategy, raddoppiando la capacità del buffer interno ogni volta che doveva essere ingrandito.
StringBuilder è stato completamente riscritto per .NET 4, ora con ropes. L'estensione dell'allocazione viene ora eseguita aggiungendo un altro pezzo di corda con un massimo di 8000 caratteri. Non abbastanza efficiente come la strategia precedente, ma evita problemi con i grandi buffer che intasano l'heap di oggetti di grandi dimensioni. Il codice sorgente è disponibile dalla fonte di riferimento se si vuole dare un'occhiata più da vicino.
Ci ha incasinato quando abbiamo aggiornato il nostro prodotto da .Net 3.5 a .Net 4.5. Stavamo usando l'oggetto generatore di stringhe come parametro per una chiamata API nativa attraverso l'interoperabilità. Il risultato è stato un sovraccarico del buffer che ha causato il crash del processo. La memoria heap si corrompeva quando l'API nativa restituiva stringhe lunghe. Abbiamo iniziato a fornire una capacità esplicita nel costruttore in modo che il buffer potesse occuparsi delle stringhe lunghe. Sorprendentemente avrebbe dovuto essere interrotto in precedenza anche per stringhe lunghe ma non veniva mai segnalato. qualche trucco in .Net 3.5 quando usiamo il generatore di stringhe come buffer per le API native? – RBT
Questo danneggia l'heap GC in entrambe le versioni di runtime. Tale corruzione non è necessariamente rilevata, devi essere fortunato. Certo, si tende ad avere più fortuna in .NET 4 –
Lo standard C# non specifica il comportamento di una classe di libreria BCL poiché non ha nulla a che fare con le specifiche della lingua.
Per quanto ne so, il comportamento effettivo non è definito in alcuna specifica ed è specifico dell'implementazione.
AFAIK, l'implementazione MS raddoppierà la capacità una volta raggiunta la capacità corrente.
Vedere this e this domande SO precedenti.
Aggiornamento:
Questo è stato modificato in .NET 4.0. come descritto da Hans in his answer. Ora vengono utilizzati ropes, aggiungendo altri 8000 caratteri alla volta.
MSDN, è però molto attenti a sottolineare che il comportamento effettivo è implementazione specifica:
Lo StringBuilder alloca dinamicamente più spazio quando richiesto e aumenta la capacità di conseguenza. Per motivi di prestazioni, un oggetto StringBuilder può allocare più memoria del necessario. La quantità di memoria allocata è specifica dell'implementazione.
Non usiamo più la strategia double-when-full. –
@Eric - Grazie per avermi corretto. Quello e la risposta di Hans mi hanno dato maggiori dettagli. – Oded
Nuovo StringBuilder (.NET 4.5 o superiore) alloca un buffer interno m_ChunkChars
richiesto dal parametro di capacità:
public StringBuilder(int capacity) { ... m_ChunkChars = new char[capacity]; ... }
Quindi, se la capacità è inferiore a 40K caratteri va sul piccolo oggetto Heap. Tuttavia (contrariamente alla credenza popolare), StringBuilder sarà ancora allocare sul mucchio di oggetti di grandi dimensioni, se, in seguito, che noi chiamiamo sb.Append(...some string larger than 40K chars...);
Una possibile soluzione può essere trovata qui: https://github.com/amikunov/Large-Object-Heap-Fix-For-.NET-String-Builder
Questo non ha nulla a che fare con ciò che la domanda sta chiedendo. – Servy
- 1. capacità StringBuilder()
- 2. Dimensioni di capacità iniziale più efficienti per StringBuilder?
- 3. Cambia capacità predefinita/fattore di carico di scala mutable.HashMap
- 4. Come tagliare la stringa di StringBuilder?
- 5. Come sapere/ottenere la capacità di hashmap?
- 6. Come clonare() StringBuilder
- 7. StringBuilder inizializzazione in Java
- 8. Come aggiungere due stringBuilder?
- 9. Semplice StringBuilder costruttore/metodo questione
- 10. boost :: La funzione membro della capacità di stable_vector non restituisce la capacità assegnata
- 11. ridurre la capacità di un vettore stl
- 12. Quanti caratteri può contenere un StringBuilder Java?
- 13. StringBuilder o + =
- 14. StringBuilder aggiunge null come "null"
- 15. Capacità di un uint64_t?
- 16. modo corretto di utilizzare StringBuilder
- 17. Perché la classe StringBuilder è sigillata?
- 18. Come rilevare le capacità Headset
- 19. Smaltimento di un oggetto StringBuilder
- 20. Rileva la capacità al passaggio del mouse
- 21. StringBuilder Vs StringWriter/StringReader
- 22. std :: vector.pop_back() modifica la capacità del vettore?
- 23. StringBuilder e byte di conversione
- 24. StringBuilder vs XmlTextWriter
- 25. Quando usare StringBuilder?
- 26. Crea StringBuilder dal byte []
- 27. Come impostare la capacità CAP_SYS_NICE su un utente Linux?
- 28. Come cancellare un vettore mantenendo la sua capacità?
- 29. Groovy StringBuilder letterale/StringBuffer
- 30. Newline character in stringbuilder
questo non è specificato in qualsiasi standard, il suo solo un dettaglio di implementazione – BrokenGlass
StringBuilder non fa parte del linguaggio C#. Fa parte delle librerie .net. –
possibile duplicato di [In che modo StringBuilder decide quanto deve essere grande la sua capacità?] (Http://stackoverflow.com/questions/4495855/how-does-the-stringbuilder-decide-how-large-its-capacity-should -be) – bzlm