views:

934

answers:

5

Similar to this question, but for VB.NET since I learned this is a language thing.

For instance, would the compiler know to translate

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

to

Dim s As String = "test this function"

and thus avoid the performance hit with the string concatenation?

+4  A: 

While I'm looking it up, here's the download page for the spec.

Section 11.2 looks like it would be the right bit - it's basically the equivalent of 7.18 in the C# 3.0 spec - but it doesn't contain the same guarantee. I suspect the compiler still does it, but I can't see any guarantee. I'll have another look though.

Section 11.2 does state that "A constant expression is an expression whose value can be fully evaluated at compile time" (my emphasis) but I can't see that it actually guarantees that it will fully evaluate it at compile time. Frankly it would be odd to make a category of expression based on this condition but not actually use it.

A quick test shows that the current VB compiler does indeed do the concatenation at compile time, but there really should be a guarantee in the spec if that's the intention.

Section 7.3 get a bit closer:

When the operands of an expression are all primitive type constants, it is possible for the compiler to evaluate the expression at compile time. Such an expression is known as a constant expression.

Now String isn't a primitive type in terms of the CLR (Type.IsPrimitive would return false) but it is in terms of the VB spec.

It's still not saying that it will evaluate it though...

Jon Skeet
now it's a race to find it in the spec. :-)
Larsenal
+7  A: 

Yes. It Does. I only tested VS 2008 but I strongly suspect previous versions did as well.

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. - Notice the string "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

}

-Jason

Jason Hernandez
+1  A: 

The compiler will optimize a string concatenation when appropriate. However, you should consider using the StringBuilder class if you don't know how many concatenations there may be.

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

From the above article:

The performance of a concatenation operation for a String or StringBuilder object depends on how often a memory allocation occurs. A String concatenation operation always allocates memory, whereas a StringBuilder concatenation operation only allocates memory if the StringBuilder object buffer is too small to accommodate the new data. Consequently, the String class is preferable for a concatenation operation if a fixed number of String objects are concatenated. In that case, the individual concatenation operations might even be combined into a single operation by the compiler. A StringBuilder object is preferable for a concatenation operation if an arbitrary number of strings are concatenated; for example, if a loop concatenates a random number of strings of user input.

Jason
+3  A: 

YES, IT DOES! LET`S PUT IT TO TEST.

Since .NET compiles all managed languages (VB, C#, C++) to IL (Intermediate Language) instructions and String type is part of CLS (Common Language Specification) all .NET Framework versions: 2.0, 3.0, 3.5, 4.0 optimizes String literals concatenation as a part of compilation process.

For instance VB.NET code below:

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

produces the following IL instruction:

L_0008: ldstr "ABC"

This clearly proves that compiler is optimizing String literal concatenation (tested in: ildasm.exe)

However if the code obove is written in separate statements:

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

no optimization is done and String concatenation is executed at run-time (performance overhead). Same applies for a single line statements with data resolved at run-time (variables, properties, methods).

Use underscore _ to connect above statements into a single statement to enforce optimization:

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

and in case you need new lines between tokens use vbCrLf (compile-time) constant to ensure optimization because using Environment.NewLine (run-time) property provides no optimization.

Hope this helps you to get edge on performance!

Paulius Paskevicius
+1  A: 

Jeff Atwood researched and blogged about this. Results?

It. Just. Doesn't. Matter!

Ivo van der Wijk