Разница в производительности конкатенации строк - PullRequest
0 голосов
/ 09 апреля 2010

Я знаю, что вы должны использовать StringBuilder при конкатенации строк, но мне просто интересно, есть ли разница в конкатенации строковых переменных и строковых литералов. Итак, есть ли разница в производительности при сборке s1, s2 и s3?

string foo = "foo";
string bar = "bar";

string s1 = "foo" + "bar";
string s2 = foo + "bar";
string s3 = foo + bar;

Ответы [ 5 ]

3 голосов
/ 09 апреля 2010

В случае, если вы представляете, на самом деле лучше использовать оператор конкатенации в классе строки. Это связано с тем, что он может предварительно вычислить длины строк, выделить буфер один раз и быстро скопировать память в буфер новой строки.

И это общее правило для объединения строк. Когда у вас есть заданное количество элементов, которые вы хотите объединить вместе (будь то 2, или 2000, и т. Д.), Лучше просто объединить их все с помощью оператора объединения следующим образом:

string result = s1 + s2 + ... + sn;

Следует отметить в вашем конкретном случае для s1:

string s1 = "foo" + "bar";

Компилятор видит, что он может оптимизировать здесь конкатенацию строковых литералов, и преобразует вышеприведенное в следующее:

string s1 = "foobar";

Обратите внимание, это только для объединения двух строковых литералов вместе. Так что, если вы должны были сделать это:

string s2 = foo + "a" + bar;

Тогда он не делает ничего особенного (но он по-прежнему вызывает Concat и предварительно вычисляет длину). Однако в этом случае:

string s2 = foo + "a" + "nother" + bar;

Компилятор переведет это на:

string s2 = foo + "another" + bar;

Если число строк, которые вы объединяете, является переменным (например, цикл, который вы не знаете заранее, сколько в нем элементов), то StringBuilder является наиболее эффективным способом объединения этих строк, так как вам всегда нужно будет повторно вычислить буфер, чтобы учесть добавляемые новые строковые записи (из которых вы не знаете, сколько осталось).

2 голосов
/ 09 апреля 2010

Компилятор может объединять литералы во время компиляции, поэтому "foo" + "bar" компилируются непосредственно в "foobar", и во время выполнения не нужно ничего делать.

Кроме этого, я сомневаюсь, что есть существенная разница.

1 голос
/ 09 апреля 2010

Ваши "знания" неверны. Вы должны иногда использовать StringBuilder при объединении строк. В частности, вы должны делать это, когда вы не можете выполнить объединение всего за одно выражение.

В этом случае код компилируется как:

string foo = "foo";
string bar = "bar";

string s1 = "foobar";
string s2 = String.Concat(foo, "bar");
string s3 = String.Concat(foo, bar);

Использование StringBuilder сделает все это менее эффективным - в частности, это приведет к объединению s1 со времени компиляции во время выполнения. Для s2 и s3 это вызовет создание дополнительного объекта (StringBuilder), а также, вероятно, выделит string, который излишне велик.

У меня есть статья , которая более подробно об этом.

1 голос
/ 09 апреля 2010

Нет разницы между s2 и s3. Компилятор позаботится о s1 за вас и объединит его во время компиляции.

0 голосов
/ 09 апреля 2010

Я бы сказал, что это должен решить компилятор. Потому что все ваши строковые сборки могут быть оптимизированы, поскольку значения уже известны.
Я предполагаю, что StringBuilder предварительно выделяет место для добавления дополнительных строк. Как вы знаете, + является бинарным оператором, поэтому невозможно создать конкатенацию более чем из двух строк одновременно. Таким образом, если вы хотите сделать s4 = s1 + s2 + s3, потребуется создать промежуточную строку (s1+s2) и только после этого s4.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...