【问题标题】:Does VB.NET optimize the concatenation of string literals?VB.NET 是否优化了字符串文字的连接?
【发布时间】:2010-09-22 09:01:36
【问题描述】:

类似于this 问题,但是对于 VB.NET,因为我了解到这是一个语言问题。

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

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

Dim s As String = "test this function"

从而避免字符串连接对性能的影响?

【问题讨论】:

    标签: .net vb.net performance optimization


    【解决方案1】:

    是的。它确实。我只测试了 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 
    }
    

    【讨论】:

      【解决方案2】:

      是的,确实如此!让我们来测试一下。

      由于 .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)

      但是,如果上面的代码写在单独的语句中:

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

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

      使用下划线 _ 将以上语句连接成一个语句来强制优化:

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

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

      希望这可以帮助您在性能上取得优势!

      【讨论】:

        【解决方案3】:

        在我查找时,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 规范而言,它

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

        【讨论】:

          【解决方案4】:

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

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

          来自以上文章:

          连接的性能 字符串操作或 StringBuilder 对象取决于如何 经常发生内存分配。一种 字符串连接操作总是 分配内存,而 StringBuilder 连接操作 仅在 StringBuilder 对象缓冲区太 小以容纳新数据。 因此,String 类是 更适合串联 如果是固定数量的String,则操作 对象被连接起来。在那里面 情况下,单独的串联 操作甚至可以合并为 编译器的单个操作。一种 StringBuilder 对象更适合于 一个连接操作,如果 任意数量的字符串是 串联;例如,如果一个循环 连接一个随机数 用户输入的字符串。

          【讨论】:

            【解决方案5】:

            Jeff Atwood 对此进行了研究并发表了博文。结果?

            It. Just. Doesn't. Matter!

            【讨论】:

              猜你喜欢
              • 2010-09-22
              • 2011-05-16
              • 1970-01-01
              • 1970-01-01
              • 2011-06-12
              • 1970-01-01
              • 2017-03-09
              • 1970-01-01
              相关资源
              最近更新 更多