Kiedy mam pusty StringBuilder
o pojemności 5 i piszę "cześć, świecie!" do tego, czy standard C# określa nową pojemność StringBuilder
? Mam niewyraźne wspomnienie, że jest to dwukrotność długości nowego napisu (aby uniknąć zmiany pojemności przy każdym nowym dołączonym ciągu).Jak zmienia się pojemność StringBuilder?
Odpowiedz
Zależy od wersji .NET, o której mówisz. Przed .NET 4 StringBuilder użył standard .NET strategy, podwajając pojemność bufora wewnętrznego za każdym razem, gdy trzeba go powiększyć.
StringBuilder został przepisany całkowicie na .NET 4, teraz używający ropes. Rozszerzenie alokacji odbywa się teraz poprzez dodanie kolejnego kawałka liny o długości do 8000 znaków. Nie tak skuteczny jak wcześniejsza strategia, ale unika kłopotów z dużymi buforami blokującymi stertę dużych obiektów. Kod źródłowy jest dostępny ze źródła referencyjnego, jeśli chcesz przyjrzeć mu się bliżej.
Zawiodło to dla nas, gdy uaktualniliśmy nasz produkt z .Net 3.5 do .Net 4.5. Użyliśmy obiektu budującego ciągi jako parametru do natywnego wywołania API poprzez interop. Doprowadziło to do problemu przekroczenia bufora, powodującego awarię procesu. Pamięć sterty ulegała uszkodzeniu, gdy natywny API zwracał długie łańcuchy. Zaczęliśmy zapewniać jawną pojemność w konstruktorze, aby bufor mógł obsłużyć długie ciągi. Z całą pewnością powinno to być wcześniej przerywane również dla długich łańcuchów, ale nigdy nie zostało zgłoszone. Interopowa warstwa działa jakaś sztuczka w .Net 3.5, gdy używamy budowniczych ciągów jako bufora dla natywnych API? – RBT
To powoduje uszkodzenie sterty GC w obu wersjach środowiska wykonawczego. Takie korupcje niekoniecznie muszą zostać wykryte, musisz mieć szczęście. Jasne, masz większe szczęście w .NET 4 –
Standard C# nie określa zachowania biblioteki biblioteki BCL, ponieważ nie ma ona nic wspólnego ze specyfikacją języka.
O ile mi wiadomo, rzeczywiste zachowanie nie jest zdefiniowane w żadnej specyfikacji i jest zależne od implementacji.
AFAIK, Wdrożenie MS podwoi wydajność po osiągnięciu obecnej przepustowości.
Zobacz wcześniejsze pytania WSTĘPNE this i this.
Aktualizacja:
ten został zmieniony w .NET 4.0. jak opisano przez Hans w his answer. Teraz używa się ropes, dodając kolejne 8000 znaków naraz.
MSDN jednak jest bardzo ostrożny, aby podkreślić, że rzeczywiste zachowanie jest realizacja specyficznych:
StringBuilder dynamicznie przydziela więcej przestrzeni gdy wymagane i zwiększa pojemność odpowiednio. Ze względu na wydajność, StringBuilder może przydzielić więcej pamięci niż potrzeba. Ilość przydzielonej pamięci jest zależna od implementacji.
Nie używamy już strategii podwójnego wyczerpania. –
@Eric - Dzięki za poprawienie mnie. To i odpowiedź Hansa dała mi więcej szczegółów. – Oded
New StringBuilder (.NET 4.5 lub nowszy) przydziela bufor wewnętrzny m_ChunkChars
wymaganych przez parametr Pojemność:
public StringBuilder(int capacity) { ... m_ChunkChars = new char[capacity]; ... }
Tak więc, jeśli pojemność jest mniejsza niż 40K znaków idzie na mały przedmiot sterty. Jednak (w przeciwieństwie do popularnego przekonania), StringBuilder nadal będzie przeznaczyć na dużej sterty Object czy później, nazywamy sb.Append(...some string larger than 40K chars...);
Ewentualna poprawka można znaleźć tutaj: https://github.com/amikunov/Large-Object-Heap-Fix-For-.NET-String-Builder
Nie ma to nic wspólnego z pytaniem. – Servy
- 1. Jak klonować() StringBuilder
- 2. Jak zwolnić nieużywaną pojemność ciągu
- 3. Zobacz, jak zmienia się python
- 4. Jak zmienia się moduł scalający?
- 5. PPL Pojemność wydajność
- 6. .NET StringBuilder - sprawdź, czy kończy się ciągiem
- 7. Int16 - pojemność bajtów in.net?
- 8. Idź plastry - pojemność/długość?
- 9. Konstruktor StringBuilder akceptuje obiekt StringBuilder - dlaczego?
- 10. Maksymalna pojemność bazy danych SQLite
- 11. Zobacz, jak zmienia się stan adresu IP.
- 12. Jak zmienia się śledzenie bazy danych SQLAlchemy?
- 13. Rosyjska strefa czasowa zmienia się
- 14. Oracle SYS_GUID nie zmienia się
- 15. Usuwanie obiektu StringBuilder
- 16. StringBuilder/StringBuffer vs. "+" Operator
- 17. java outOfMemoryError z stringbuilder
- 18. Przycisk obrazu zmienia się programowo?
- 19. Nazwa użytkownika ASP.NET zmienia się
- 20. Newline character in stringbuilder
- 21. StringBuilder w Flex
- 22. Dlaczego StringBuilder nie drukuje?
- 23. Kiedy używać StringBuilder?
- 24. wyzwalania backbone.js zmienia się, gdy wartość nie zmienia
- 25. C# StringBuilder: Sprawdź, czy kończy się na nowej linii
- 26. StringWriter lub StringBuilder
- 27. Streamwriter vs StringBuilder
- 28. Napisz StringBuilder do strumienia
- 29. Stringbuilder w CIL (MSIL)
- 30. StringBuilder i bajt konwersja
ten nie jest określony w dowolnym standardzie, jej tylko szczegółów wdrażania – BrokenGlass
StringBuilder nie jest częścią języka C#. Jest częścią bibliotek .net. –
możliwy duplikat [W jaki sposób StringBuilder decyduje, jak duża powinna być jego pojemność?] (Http://stackoverflow.com/questions/4495855/how-does-the-stringbuilder-decide-how-large-its-capacity-should -be) – bzlm