本地Dim与静态变量

时间:2014-05-11 19:15:38

标签: vb.net performance il

  

IL 角度来看,本地 Dim 变量与本地静态变量之间的主要差异(性能明智)是什么?< / p>

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

  • A: Dim
  • B: 静态

Chart

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

结果几乎相同:

  • A: 358,3624
  • B: 538.8570

2 个答案:

答案 0 :(得分:4)

性能的主要差异不在于如何分配变量,而在于如何分配变量。

局部变量在堆栈上分配,完全没有时间。从字面上看。通过移动堆栈指针完成分配,无论如何都要为该方法创建堆栈帧,因此分配局部变量不会花费更多时间。

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

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

答案 1 :(得分:-2)

VB实例静态变量如果在实例方法中出现,则每个实例分配一次。如果它们出现在Shared方法中,它们只会被分配一次。