From the IL perspective, what are the main differences (performance wise) between a local Dim variable and a local Static variable?
I've always thought that Dim would allocate storage space every time, whilst Static would allocate storage space only once, hence faster. But as you can see below, this is not the case.
- A: Dim
- B: Static
Public Class Form1
Public Sub New()
Me.InitializeComponent()
Dim b As New Button() With {.Text = "Run", .Height = 30, .Location = New Point(10, 10)}
AddHandler b.Click, AddressOf Me.Run
Me.Controls.Add(b)
End Sub
Private Sub Run(sender As Object, e As EventArgs)
Dim count As Integer = 10000
Dim watch As New Stopwatch()
Dim list As New Test(Of Control)(count)
Dim last As Control = list.Items(count - 1)
Dim a, b As Double, i As Integer
For i = 1 To 10000
watch.Restart()
list.IndexOfA(last)
a += watch.Elapsed.TotalMilliseconds
Next
For i = 1 To 10000
watch.Restart()
list.IndexOfB(last)
b += watch.Elapsed.TotalMilliseconds
Next
watch.Stop()
Array.ForEach(Of Control)(list.Items, Sub(c As Control) c.Dispose())
list = Nothing
MessageBox.Show(String.Format("A: {0}{1}B: {2}", a.ToString("F4"), Environment.NewLine, b.ToString("F4")))
End Sub
Public Class Test(Of T As {Class, New})
Public Sub New(count)
If (count < 0) Then Throw New ArgumentOutOfRangeException("count")
Dim items As T() = New T(count - 1) {}
For index As Integer = (count - 1) To 0 Step -1
items(index) = New T()
Next
Me.Items = items
End Sub
Public Function IndexOfA(item As T) As Integer
Dim index As Integer
Dim length As Integer
Dim item2 As T
length = (Me.Items.Length - 1)
For index = 0 To length
item2 = Me.Items(index)
If (item2 Is item) Then
Return index
End If
Next
Return -1
End Function
Public Function IndexOfB(item As T) As Integer
Static index As Integer
Static length As Integer
Static item2 As T
length = (Me.Items.Length - 1)
For index = 0 To length
item2 = Me.Items(index)
If (item2 Is item) Then
Return index
End If
Next
Return -1
End Function
Public ReadOnly Items As T()
End Class
End Class
Edit
As per comment, I've edited the code so it don't "restart the stopwatch at every loop iteration".
watch.Start()
For i = 1 To 10000
list.IndexOfA(last)
Next
watch.Stop()
a = watch.Elapsed.TotalMilliseconds
watch.Restart()
For i = 1 To 10000
list.IndexOfB(last)
Next
watch.Stop()
b = watch.Elapsed.TotalMilliseconds
The results are almost the same:
- A: 358,3624
- B: 538.8570