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

Похоже на этот вопрос, но для VB.NET, поскольку я узнал, что это язык.

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

Dim s As String = "test" + "this" + "Функция"

до

Dim s As String = "test this function"

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

Ответы [ 5 ]

11 голосов
/ 18 ноября 2008

Да. Оно делает. Я только протестировал VS 2008, но я сильно подозреваю, что предыдущие версии тоже.

VB.NET

Public Class Class1


    Dim s As String = "test " + "this " + "function"

    Public Function test() As String
        Return s
    End Function

End Class

I.L. - Обратите внимание на строку «проверить эту функцию»

{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: call instance void [mscorlib]System.Object::.ctor()
    L_0006: nop 
    L_0007: ldarg.0 
    L_0008: ldstr "test this function"
    L_000d: stfld string ClassLibrary1.Class1::s
    L_0012: nop 
    L_0013: ret 
}
5 голосов
/ 21 сентября 2010

ДА, ЭТО ДЕЛАЕТ! ДАВАЙТЕ ПРОВЕРИТЬ.

Поскольку .NET компилирует все управляемые языки (VB, C #, C ++) в инструкции IL (промежуточный язык), а тип String является частью CLS (Common Language Specification) всех версий .NET Framework: 2.0, 3.0, 3.5, 4.0 оптимизирует String конкатенацию литералов как часть процесса компиляции.

Например, код VB.NET ниже:

Dim s As String = "A" & "B" & "C" 

создает следующую инструкцию IL:

L_0008: ldstr "ABC"

Это ясно доказывает, что компилятор оптимизирует String конкатенацию букв (протестировано в: ildasm.exe)

Однако, если указанный выше код записан в отдельных выражениях:

Dim s As String = "A"
s &= "B"
s &= "C" 

оптимизация не выполняется и String конкатенация выполняется во время выполнения (снижение производительности). То же самое касается однострочных операторов с данными, разрешенными во время выполнения (переменные, свойства, методы).

Используйте подчеркивание _, чтобы связать вышеприведенные операторы в единый оператор для обеспечения оптимизации:

Dim s As String = "A" _
& "B" _
& "C" _

и в случае, если вам нужны новые строки между токенами, используйте vbCrLf (время компиляции), чтобы обеспечить оптимизацию, потому что использование свойства Environment.NewLine (время выполнения) не обеспечивает оптимизации.

Надеюсь, это поможет вам получить преимущество в производительности!

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

Пока я смотрю, вот страница загрузки для спецификации .

Раздел 11.2 выглядит так: будет правильным битом - в основном это эквивалент 7.18 в спецификации C # 3.0 - но он не содержит той же гарантии. Я подозреваю, что компилятор все еще делает это, но я не вижу никакой гарантии. Я еще посмотрю.

В разделе 11.2 действительно говорится, что «константное выражение - это выражение , значение которого может быть полностью оценено во время компиляции » (мой акцент), но я не вижу, что оно действительно гарантирует, что оно полностью оценит его во время компиляции. Честно говоря, было бы странно создавать категорию выражений на основе этого условия, но не использовать их на самом деле.

Быстрый тест показывает, что текущий компилятор VB действительно выполняет конкатенацию во время компиляции, но на самом деле должна быть гарантией в спецификации, если это намерение.

Раздел 7.3 немного ближе:

Когда операнды выражения все константы примитивного типа, это возможно для компилятора оценить выражение во время компиляции. такие выражение известно как константа выражение.

Теперь String не является примитивным типом с точки зрения CLR ( Type.IsPrimitive будет возвращать false), но равен с точки зрения спецификации VB.

Это все еще не говорит, что это будет оценивать это хотя ...

1 голос
/ 21 сентября 2010

Джефф Этвуд исследовал и написал в блоге об этом. Результаты?

It. Просто. Не имеет. Matter!

1 голос
/ 18 ноября 2008

Компилятор оптимизирует конкатенацию строк при необходимости. Однако вам следует рассмотреть возможность использования класса StringBuilder, если вы не знаете, сколько может быть объединений.

http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx

Из вышеприведенной статьи:

Производительность конкатенации операция для строки или Объект StringBuilder зависит от того, как часто происходит выделение памяти. Операция конкатенации строк всегда выделяет память, тогда как Операция конкатенации StringBuilder только выделяет память, если Буфер объекта StringBuilder слишком маленький для размещения новых данных. Следовательно, класс String предпочтительнее для объединения операция, если фиксированное число строк объекты объединены. В этом случай, индивидуальная конкатенация операции могут быть даже объединены в одна операция компилятора. Объект StringBuilder предпочтительнее для операция конкатенации, если произвольное количество строк сцеплены; например, если цикл объединяет случайное число строки пользовательского ввода.

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