2008-11-14 2 views
9

Как и для this вопрос, но для VB.NET, так как я узнал, что это язык.VB.NET оптимизирует конкатенацию строковых литералов?

Например, будет ли компилятор знать, чтобы перевести

Dim сек As String = "это" "функция" "тест" + +

в

Dim s As String = "test this function" 

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

ответ

11

Да. Оно делает. Я только тестировал 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 

И.Л. - Обратите внимание на строку «Проверить эту функцию»

{ 
    .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 
} 
4

Пока я смотрю, here's the download page for the spec.

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

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

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

Раздел 7.3 получить немного ближе:

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

Теперь Строка не примитивный тип в терминах CLR (Type.IsPrimitive вернет ложь), но в терминах VB спецификации.

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

+0

теперь это гонка, чтобы найти его в спецификации. :-) – Larsenal 2008-11-14 15:59:05

1

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

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

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

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

5

ДА, ЭТО ДЕЛАЕТ! ПОЗВОЛЯЙТЕ, ЧТО ИСКАТЬ ИСПЫТАТЬ.

Поскольку .NET компилирует все управляемые языки (VB, C#, C++) для IL (Intermediate Language) инструкции и String типа является частью CLS (Common Specification Language) все версии .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 (run-time) не обеспечивает никакой оптимизации.

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

Смежные вопросы