ShortCut Operators

Mehyar

Well-known member
Joined
Jun 9, 2003
Messages
371
Location
Lebanon
In VB.NET you can use shortcut assignment operators for example:

x += 1 is equivalent to x = x + 1
And
s &= "Hello" is equivalent to s = s & "Hello"

To me the latter expressions are more readable, but I have read on one website that the shortcut assignment is faster when executing code becasue it loads the lefthand side into memory only once, while the latter does so twice. Is this true ??
 
Do you have a link to the website? It seems unlikely there would be a difference in how they compile as the operations are basically the same.
 
There is no difference. The latter case is optimized correctly to make it as effecient as the former.
 
Got to disagree with them there. Just created a simple test project

Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim y As String
    y &= "yyy"
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    Dim x As String
    x = x & "xxx"
End Sub

and in both cases the MSIL generated was the same (in fact it didnt really differ between debug and release mode)

Code:
.method private instance void  Button1_Click(object sender,
                                             class [mscorlib]System.EventArgs e) cil managed
{
  // Code size       13 (0xd)
  .maxstack  2
  .locals init (string V_0)
  IL_0000:  ldloc.0
  IL_0001:  ldstr      "yyy"
  IL_0006:  call       string [mscorlib]System.String::Concat(string,
                                                              string)
  IL_000b:  stloc.0
  IL_000c:  ret
} // end of method Form1::Button1_Click


.method private instance void  Button2_Click(object sender, 
                                        class [mscorlib]System.EventArgs e) cil managed
{
  // Code size       13 (0xd)
  .maxstack  2
  .locals init (string V_0)
  IL_0000:  ldloc.0
  IL_0001:  ldstr      "xxx"
  IL_0006:  call       string [mscorlib]System.String::Concat(string,
                                                              string)
  IL_000b:  stloc.0
  IL_000c:  ret
} // end of method Form1::Button2_Click

you will notice that in both cases it calls the String.Concat anyway - which also answers the other thread you posted on strings ;)

edit: thought about something else

Also just retried it using a string variable rather than a hardcode string and again the two methods produced the same code.
 
Yea thanks, thats great .....

Way to go ..

Just a question, how do you see the IL code generated for your code ??
 
Last edited by a moderator:
ildasm.exe to view the code.

and another update though....

If you are using an object with a property that returns a string things do change......

Code:
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim y As New Test
        Dim z As String
        z = "yyy"
        y.Testing &= z
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim x As Test
        Dim z As String
        z = "xxx"
        x.Testing = x.Testing & z
    End Sub
End Class

Public Class Test
    Private x As String

    Public Property Testing() As String
        Get
            Return x
        End Get
        Set(ByVal Value As String)
            x = Value
        End Set
    End Property
End Class

The x.Testing = x.Testing & z way produces the following MSIL
Code:
.method private instance void  Button2_Click(object sender,
                                             class [mscorlib]System.EventArgs e) cil managed
{
  // Code size       31 (0x1f)
  .maxstack  3
  .locals init (class WindowsApplication2.Test V_0,
           string V_1)
  IL_0000:  newobj     instance void WindowsApplication2.Test::.ctor()
  IL_0005:  stloc.0
  IL_0006:  ldstr      "xxx"
  IL_000b:  stloc.1
  IL_000c:  ldloc.0
  IL_000d:  ldloc.0
  IL_000e:  callvirt   instance string WindowsApplication2.Test::get_Testing()
  IL_0013:  ldloc.1
  IL_0014:  call       string [mscorlib]System.String::Concat(string,
                                                              string)
  IL_0019:  callvirt   instance void WindowsApplication2.Test::set_Testing(string)
  IL_001e:  ret
} // end of method Form1::Button2_Click

while the y.Testing &= z method gives
Code:
.method private instance void  Button1_Click(object sender,
                                             class [mscorlib]System.EventArgs e) cil managed
{
  // Code size       33 (0x21)
  .maxstack  3
  .locals init (class WindowsApplication2.Test V_0,
           string V_1,
           class WindowsApplication2.Test V_2)
  IL_0000:  newobj     instance void WindowsApplication2.Test::.ctor()
  IL_0005:  stloc.0
  IL_0006:  ldstr      "yyy"
  IL_000b:  stloc.1
  IL_000c:  ldloc.0
  IL_000d:  stloc.2
  IL_000e:  ldloc.2
  IL_000f:  ldloc.2
  IL_0010:  callvirt   instance string WindowsApplication2.Test::get_Testing()
  IL_0015:  ldloc.1
  IL_0016:  call       string [mscorlib]System.String::Concat(string,
                                                              string)
  IL_001b:  callvirt   instance void WindowsApplication2.Test::set_Testing(string)
  IL_0020:  ret
} // end of method Form1::Button1_Click
which is slightly different. Not too sure how much difference this would make in performance though. Also this MSIL will get JIT compiled on a run anyway so there may not be an awful lot of difference in this case.
More complex objects or more complex Get / Set procedures may be affected though.
 
Back
Top