Bjø*_*sjå 0 vb.net performance il
从IL 的角度来看,局部Dim变量和局部 静态变量之间的主要区别(性能方面)是什么?
我一直认为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
Run Code Online (Sandbox Code Playgroud)
编辑
根据评论,我已经编辑了代码,因此它不会“在每次循环迭代时重新启动秒表”。
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
Run Code Online (Sandbox Code Playgroud)
结果几乎相同:
性能的主要区别不在于变量的分配方式,而在于它们的访问方式。
局部变量在栈上分配,完全不需要时间。字面上地。分配是通过移动堆栈指针来完成的,无论如何都会为该方法创建一个堆栈帧,因此分配局部变量不会再花费任何时间。
实例方法中的静态变量作为类数据的一部分分配,在这种情况下只分配一次。分配另一个变量仅意味着分配更多数据,因此不会增加时间。
访问变量是另一回事。通过寻址堆栈帧的一部分来访问局部变量,这很容易。另一方面,静态变量是通过获取指向类的静态数据的指针来访问的,然后在该变量的偏移量处寻址该变量。这意味着每次访问静态变量都需要更多的指令。