Страницы

Поиск по вопросам

четверг, 12 декабря 2019 г.

Строки в c#. String \ StringBuilder

#c_sharp


Ребят, у меня возникли вопросы по строкам в c#.


  
  Чем отличается класс String от StringBuilder? 
  Зачем нужно такое разделение?
  В чем преимущества того и другого? 
  Что из этого лучше использовать? 
  Почему StringBuilder лучше использовать для работы с большими объемами текста?
  


По возможности ответьте с примерами. Заранее спасибо за ответ.
    


Ответы

Ответ 1



String - это строки. Они неизменяемые т.е. конкретную строку нельзя подправить/дописать/укоротить. Любые операции над строками приводят к созданию новой строки (с копированием всего текста). При этом старая строка уходит в мусор (если у вас не остается на нее ссылки). Так сделано из соображений Экономии памяти - не надо подстраховываться и копировать строку "на всякий случай" при передаче куда-то в другой метод. Он ее точно никак не испортит. Производительности - можно высчитывать хэш строки один раз, и не заморачиваться с поддержанием его актуальности. Это дает быстрые сравнения строк на равенство (особенно если строки разные). Безопасности - код может спокойно работать с пришедшими извне строками, не опасаясь что кто-то влезет в строку по дороге. Простоты работы с несколькими потоками - нет проблемы одновременных изменений. Соответственно, при сборке большой строки из многих маленких эта особенность - неизменяемость строк - приводит к множественному копированию данных и к генерации большого количества мусора. Для решения этой проблемы есть класс StringBuilder. Это не "строка", а класс для сборки строк из кусков, позволяющий в конце получить результирующую строку вызовом StringBuilder.ToString(). Если вам надо просто работать со строками - используете String Если вам надо собрать одну большую строку из пачки маленьких - используете StringBuilder

Ответ 2



String не изменяемый тип. То есть если Вы создадите строку потом добавите ей несколько символов то это будет не старая модифицированная строка, а в памяти аллоцируется новый объект System.String, который будет содержать в себе новую строку. При этом старый объект продолжает существовать в куче пока не произойдет сборка мусора. Такой вот безобидный код: string str = string.Empty; for(int i = 0; i < 1000; ++i) { str += "a"; } Создаст в памяти 1000 потенциальных кандидатов для GC. При вызове метода например Append объекта StringBuilder будет изменятся уже существующая область памяти. Что бы не загружать GC лишними операциями. Преимущества очевидны -- Если у вас одна строка (например константа) то типа System.String вполне достаточно. Если же вы заранее знаете что будете много изменять строку то класс StringBuilder упростить жизнь GC и CLR. Врятли это как то скажется на производительности, если у Вас не большая система и реально вы не почувствуете разницу. Но когда в проекте идет работа с миллионами строк то тогда StringBuilder не заменим (если конечно же Вы не напишете свой механизм работы со строками на неуправляемом коде или в unsafe-коде). Ответы на остальные вопросы очевидны. Эта тема очень детально описана в книге "CRL via C#" Джеффри Рихтера.

Комментариев нет:

Отправить комментарий