Чтобы ответить на ваш вопрос: Контатенация строк в C # (и .NET в целом) "безопасна", но выполнение ее в замкнутом цикле, как вы описываете, может вызвать серьезные нагрузка на память и нагрузку на сборщик мусора.
Я бы рискнул предположить, что ошибки, о которых вы говорите, были в некотором роде связаны с исчерпанием ресурсов, но было бы полезно, если бы вы могли предоставить более подробную информацию - например, получили ли вы исключение? Приложение завершилось аварийно?
Справочная информация. Строки .NET неизменяемы, поэтому при такой конкатенации:
var stringList = new List<string> {"aaa", "bbb", "ccc", "ddd", //... };
string result = String.Empty;
foreach (var s in stringList)
{
result = result + s;
}
Это примерно эквивалентно следующему:
string result = "";
result = "aaa"
string temp1 = result + "bbb";
result = temp1;
string temp2 = temp1 + "ccc";
result = temp2;
string temp3 = temp2 + "ddd";
result = temp3;
// ...
result = tempN + x;
Цель этого примера - подчеркнуть, что каждый раз, когда цикл приводит к выделению новой временной строки.
Поскольку строки неизменяемы, среда выполнения не имеет альтернативных вариантов, кроме как выделять новую строку каждый раз, когда вы добавляете другую строку в конец вашего результата.
Хотя строка result
постоянно обновляется, чтобы указать на самый последний и лучший промежуточный результат, вы создаете много этих безымянных временных строк, которые почти сразу становятся пригодными для сборки мусора.
В конце этой конкатенации у вас будут следующие строки, хранящиеся в памяти (при условии, для простоты, что сборщик мусора еще не запущен).
string a = "aaa";
string b = "bbb";
string c = "ccc";
// ...
string temp1 = "aaabbb";
string temp2 = "aaabbbccc";
string temp3 = "aaabbbcccddd";
string temp4 = "aaabbbcccdddeee";
string temp5 = "aaabbbcccdddeeefff";
string temp6 = "aaabbbcccdddeeefffggg";
// ...
Хотя все эти неявные временные переменные подлежат сборке мусора почти сразу, они все равно должны быть выделены. При выполнении конкатенации в замкнутом цикле это создаст большую нагрузку на сборщик мусора и, по крайней мере, заставит ваш код работать очень медленно. Я видел влияние этого на производительность на собственном опыте, и оно становится поистине драматичным, когда ваша объединенная строка становится больше.
Рекомендуемый подход - всегда использовать StringBuilder
, если вы выполняете несколько конкатенаций строк. StringBuilder
использует изменяемый буфер, чтобы уменьшить количество выделений, необходимых для создания вашей строки.
person
Daniel Fortunov
schedule
22.04.2009