局部变暗与静态变量

Bjø*_*sjå 0 vb.net performance il

IL 的角度来看,局部Dim变量和局部 静态变量之间的主要区别(性能方面)是什么?

我一直认为Dim每次都会分配存储空间,而Static只会分配一次存储空间,因此速度更快。但正如您在下面看到的,情况并非如此。

  • 答: 昏暗
  • B: 静态

图表

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)

结果几乎相同:

  • 答: 358,3624
  • 乙: 538.8570

Guf*_*ffa 5

性能的主要区别不在于变量的分配方式,而在于它们的访问方式。

局部变量在栈上分配,完全不需要时间。字面上地。分配是通过移动堆栈指针来完成的,无论如何都会为该方法创建一个堆栈帧,因此分配局部变量不会再花费任何时间。

实例方法中的静态变量作为类数据的一部分分配,在这种情况下只分配一次。分配另一个变量仅意味着分配更多数据,因此不会增加时间。

访问变量是另一回事。通过寻址堆栈帧的一部分来访问局部变量,这很容易。另一方面,静态变量是通过获取指向类的静态数据的指针来访问的,然后在该变量的偏移量处寻址该变量。这意味着每次访问静态变量都需要更多的指令。