#c# #.net #tostring
#c# #.net #tostring
Вопрос:
Мне любопытен ToString()
метод в C #. Возьмем, к примеру, следующее:
object height = 10;
string heightStr = height.ToString();
Когда я вызываю ToString()
on height
, я получаю обратно строковый тип. Выделяет ли среда выполнения память для этой строки?
Комментарии:
1. toString () предназначена для людей, производительность не является проблемой, поскольку они не читают так быстро. Должно быть в любом случае.
Ответ №1:
Да, среда выполнения собирается выделить память для любого объекта string, который вы создаете или запрашиваете, включая тот, который возвращается из вызова метода.
Но нет, это абсолютно не то, о чем вам нужно беспокоиться. Это не окажет какого-либо заметного влияния на производительность вашего приложения, и вы никогда не должны поддаваться искушению преждевременно оптимизировать код.
Int32.ToString
Метод чрезвычайно быстр. Он обращается к машинному коду, написанному на уровне среды CLR, что вряд ли будет узким местом производительности в любом приложении.
Фактически, реальной проблемой производительности здесь будет боксирование, то есть процесс преобразования типа значения в type object
и обратно. Это произойдет потому, что вы объявили height
переменную как type object
, а затем присвоили ей целочисленное значение.
Гораздо лучше height
явно указывать тип int
, например, так:
int height = 10;
string heightStr = height.ToString();
Комментарии:
1. Один набор упаковок / распаковок не более неэффективен, чем выделение строки.
2. @Matti: Нет, одного набора может и не быть. Мне нужно было бы посмотреть данные о производительности, чтобы быть уверенным, но здесь это совершенно неуместно. Различие, которое я пытался провести, заключается в том, что боксирование — это то, чего обычно стоит избегать. Это считается «плохой практикой» при написании . ЧИСТЫЙ код, и это, безусловно, то, о чем должен знать каждый. Выделение строк не является проблемой, и этого не следует избегать. Существует гораздо больший потенциал для повторных операций упаковки / распаковки, которые могут вызвать проблемы с производительностью в приложении.
3. В качестве небольшого примечания : блокировка также возникает, если вы вызываете виртуальный метод (такой как toString()) для переменной / выражения типа значения, которое явно не переопределяет его . В случае с
int
существует явное значение int. toString(), но это не всегда так.4. Re «для любого объекта string, который вы создаете или запрашиваете», конечно, также существует проблема интернирования — здесь это неприменимо, но «любой» — это большое утверждение
5. Я вынужден не согласиться с вступительным заявлением. Бывают ситуации, когда это может привести к проблемам с производительностью. Если бы это происходило в замкнутом цикле много раз, совокупный эффект распределений мог бы привести к дорогостоящей сборке мусора. В игре очень заметны сборки мусора. В сборщике одного поколения, подобном тому, что используется в compact Framework, вы также рискуете фрагментацией, что приводит к еще большему объему работы для сборщика.
Ответ №2:
ДА. При создании нового экземпляра класса (как в данном случае делается с классом string) для экземпляра будет выделена память.
Комментарии:
1. Я не совсем уверен, какое значение здесь имеет тот факт, что строки являются неизменяемыми. Он не модифицирует существующий экземпляр
String
класса, а скорее присваивает результатToString
функции переменной, введенной какstring
. Это приведет к созданию нового экземпляра класса, даже если он не был неизменяемым.2. @Cody Я упомянул это, чтобы подчеркнуть тот факт, что всем экземплярам string выделяется новый адрес памяти. Вы правы, это не очень актуально, но я подумал, что это может внести некоторую дополнительную ясность. В любом случае, я удалил упоминание о неизменяемости, чтобы избежать путаницы.