В некоторых случаях это устарело из-за оптимизаций, выполняемых компилятором, но общая проблема заключается в следующем коде:
string myString="";
for(int i=0;i<x;i++)
{
myString += "x";
}
будет действовать следующим образом (каждый шаг является следующей итерацией цикла):
- построить строковый объект длиной 1 и значением "x"
- Создайте новый строковый объект размером 2, скопируйте в него старую строку «x», добавьте «x» в положение 2.
- Создайте новый строковый объект размером 3, скопируйте в него старую строку «xx», добавьте «x» в позицию 3.
- ... и т. Д.
Как видите, на каждой итерации приходится копировать еще один символ, в результате чего мы выполняем 1 + 2 + 3 + 4 + 5 + ... + N операций в каждом цикле. Это операция O (n ^ 2). Однако, если бы мы заранее знали, что нам нужно только N символов, мы могли бы сделать это за одно выделение, скопировав всего N символов из строк, которые мы использовали, - просто операция O (n).
StringBuffer / StringBuilder избегают этого, потому что они изменчивы, и поэтому не нужно повторять копирование одних и тех же данных снова и снова (при условии, что в их внутреннем буфере есть место для копирования). Они избегают выполнения выделения и копирования пропорционально количеству добавлений, выполненных путем чрезмерного выделения их буфера пропорционально его текущему размеру, давая добавление амортизированного O (1).
Однако стоит отметить, что часто компилятор может автоматически оптимизировать код в стиле StringBuilder (или лучше - поскольку он может выполнять постоянное сворачивание и т. Д.).