Оптимизирует ли C # конкатенацию строковых литералов? - PullRequest
41 голосов
/ 14 ноября 2008

Например, знает ли компилятор перевести

string s = "test " + "this " + "function";

до

string s = "test this function";

и, таким образом, избежать снижения производительности при конкатенации строк?

Ответы [ 7 ]

46 голосов
/ 14 ноября 2008

Да. Это гарантировано спецификацией C #. Это в разделе 7.18 (спецификации C # 3.0):

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

(«Требования, перечисленные выше» включают оператор +, применяемый к двум константным выражениям.)

См. Также этот вопрос .

21 голосов
/ 14 ноября 2008

Просто примечание по связанной теме - компилятор C # также «оптимизирует» несколько конкатенаций с использованием не-литералов, используя оператор «+» для одного вызова многопараметрической перегрузки String.Concat ) метод.

Итак

string result = x + y + z;

компилируется во что-то эквивалентное

string result = String.Concat( x, y, z);

, а не более наивная возможность:

string result = String.Concat( String.Concat( x, y), z);

Ничего страшного, но я просто хотел добавить этот бит к обсуждению оптимизации конкатенации строкового литерала. Я не знаю, является ли это поведение обязательным для языкового стандарта или нет.

7 голосов
/ 14 ноября 2008

Да.

C # не только оптимизирует объединение строковых литералов, но и объединяет эквивалентные строковые литералы в константы и использует указатели для ссылки на все ссылки на одну и ту же константу.

5 голосов
/ 14 января 2012

Да - Вы можете увидеть это в явном виде, используя ILDASM.

Пример:

Вот программа, похожая на ваш пример, за которой следует скомпилированный код CIL:

Примечание: я использую функцию String.Concat () просто чтобы посмотреть, как компилятор обрабатывает два разных метода конкатенации.

Программа

class Program
{
    static void Main(string[] args)
    {
        string s = "test " + "this " + "function";
        string ss = String.Concat("test", "this", "function");
    }
}

ILDASM

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       29 (0x1d)
  .maxstack  3
  .locals init (string V_0,
           string V_1)
  IL_0000:  nop
  IL_0001:  ldstr      "test this function"
  IL_0006:  stloc.0
  IL_0007:  ldstr      "test"
  IL_000c:  ldstr      "this"
  IL_0011:  ldstr      "function"
  IL_0016:  call       string [mscorlib]System.String::Concat(string,
                                                              string,
                                                              string)
  IL_001b:  stloc.1
  IL_001c:  ret
} // end of method Program::Main

Обратите внимание, как в IL_0001 компилятор создал константу «протестировать эту функцию», а не то, как компилятор обрабатывает функцию String.Concat () - которая создает константу для каждого из параметров .Concat (), а затем вызывает. Функция Concat ().

4 голосов
/ 14 ноября 2008

Изо рта лошади:

Конкатенация - это процесс добавления одной строки к концу другой строки. Когда вы объединяете строковые литералы или строковые константы с помощью оператора +, компилятор создает одну строку. Конкатенация во время выполнения не происходит. Тем не менее, строковые переменные могут быть объединены только во время выполнения. В этом случае вы должны понимать влияние различных подходов на производительность.

http://msdn.microsoft.com/en-us/library/ms228504.aspx

2 голосов
/ 11 февраля 2011

У меня был похожий вопрос, но про VB.NET вместо C #. Самый простой способ убедиться в этом - просмотреть скомпилированную сборку в Reflector.

Ответ был таков: и компилятор C #, и VB.NET оптимизируют конкатенацию строковых литералов.

2 голосов
/ 14 ноября 2008

Полагаю, ответ на этот вопрос - да, но вам нужно посмотреть, что выполнил компилятор ... просто скомпилировать и использовать на нем рефлектор: -)

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