类似于this问题,但对于VB.NET,因为我知道这是一种语言事物。
例如,编译器是否知道翻译
Dim s As String =“test”+“this”+ “功能”
到
Dim s As String = "test this function"
从而避免字符串连接的性能损失?
答案 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对此进行了研究和博客。结果?