VB.NET是否优化了字符串文字的串联?

时间:2008-11-14 15:55:04

标签: .net vb.net performance optimization

类似于this问题,但对于VB.NET,因为我知道这是一种语言事物。

例如,编译器是否知道翻译

  

Dim s As String =“test”+“this”+   “功能”

Dim s As String = "test this function"

从而避免字符串连接的性能损失?

5 个答案:

答案 0 :(得分: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

I.L。 - 注意字符串“test this function”

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

答案 1 :(得分:5)

是的,它确实如此!让我们去测试。

由于.NET将所有托管语言(VB,C#,C ++)编译为IL(中间语言)指令,String类型是CLS(公共语言规范)的一部分,所有.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中测试)

但是,如果代码obove是用单独的语句编写的:

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

没有进行优化,并且在运行时执行String连接(性能开销)。同样适用于在运行时解析数据的单行语句(变量,属性,方法)。

使用下划线_将上述语句连接到单个语句中以强制优化:

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

如果您需要在令牌之间使用新行,请使用vbCrLf(编译时)常量来确保优化,因为使用Environment.NewLine(运行时)属性不提供优化。

希望这有助于您在性能方面取得优势!

答案 2 :(得分:4)

我正在查找,here's the download page for the spec

第11.2节看起来 是正确的位 - 它基本上相当于C#3.0规范中的7.18 - 但它不包含相同的保证。我怀疑编译器仍然这样做,但我看不出任何保证。我会再看看。

第11.2节确实声明“一个常量表达式是一个表达式,它的值可以在编译时完全评估”(我的重点),但我看不出它实际上保证它 将在编译时对其进行全面评估。坦率地说,根据这个条件制作一个表达类别但实际上并没有使用它会很奇怪。

快速测试表明,当前的VB编译器确实在编译时进行了连接,但是如果有意的话,那么应该是规范中的保证。

第7.3节更接近:

  

表达式的操作数是   所有原始类型常量,它是   编译器可以评估   编译时的表达式。这样   表达式称为常量   表达

现在,就CLR而言,String不是原始类型(Type.IsPrimitive将返回false)但是根据VB规范它

它仍然没有说它评估它...

答案 3 :(得分:1)

编译器将在适当时优化字符串连接。但是,如果您不知道可能存在多少个连接,则应考虑使用StringBuilder类。

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

从上面的文章:

  

串联的表现   String或的操作   StringBuilder对象取决于方式   通常会发生内存分配。一个   字符串连接操作始终   分配内存,而a   StringBuilder连接操作   只有分配内存   StringBuilder对象缓冲区也是如此   小到容纳新数据。   因此,String类是   最好是串联   操作如果是固定数量的String   对象是连接的。在那里面   个案,个别串联   甚至可以将操作合并到一起   编译器的单个操作。一个   StringBuilder对象更适合   一个连接操作,如果一个   任意数量的字符串   级联;例如,如果一个循环   连接随机数   用户输入字符串。

答案 4 :(得分:1)

Jeff Atwood对此进行了研究和博客。结果?

It. Just. Doesn't. Matter!