从 IL 角度来看,本地 Dim 变量与本地静态变量之间的主要差异(性能明智)是什么?< / p>
我一直认为Dim每次都会分配存储空间,而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
修改
根据评论,我已编辑了代码,因此它不会在每次循环迭代时重新启动秒表&#34;。
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
结果几乎相同:
答案 0 :(得分:4)
性能的主要差异不在于如何分配变量,而在于如何分配变量。
局部变量在堆栈上分配,完全没有时间。从字面上看。通过移动堆栈指针完成分配,无论如何都要为该方法创建堆栈帧,因此分配局部变量不会花费更多时间。
实例方法中的静态变量被分配为类的数据的一部分,在这种情况下只执行一次。分配另一个变量只意味着分配了更多的数据,因此不会增加时间。
访问变量是另一回事。通过寻址堆栈帧的一部分来访问局部变量,这很容易。另一方面,通过获取指向类的静态数据的指针,然后在偏移量处寻址变量来访问静态变量。这意味着每次访问静态变量都需要更多指令。
答案 1 :(得分:-2)
VB实例静态变量如果在实例方法中出现,则每个实例分配一次。如果它们出现在Shared方法中,它们只会被分配一次。