質問

以下のコードは、「for each」がループは「i to n」よりも約10%高速です。ループ、ただし「for each」ループは新しいメモリに567kを作成しますか?これは正解?速度とメモリ使用量に関して、一般的にどの方法が最も効率的ですか?

VBでこのコードを実行する場合は、ボタンと2つのラベルをフォームに追加するだけです。

Public Class StateObject
    Public WorkSocket As String = "FFFFFFFFFFFF"
    Public BufferSize As Integer = 32767
    Public Buffer(32767) As Byte
End Class

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    For cnt As Integer = 1 To 250
        Dim StateObjecter As New StateObject
        ClientNetList.Add(cnt.ToString, StateObjecter)
    Next
End Sub


Private ClientNetList As New SortedList(Of String, StateObject)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim stop1 As New Stopwatch
    Dim stop2 As New Stopwatch

    Dim TotalMemory1 As Integer = GC.GetTotalMemory(False)
    stop1.Start()
    For cnt As Integer = 1 To 1000000
        For i = 0 To ClientNetList.Count - 1
            ClientNetList.Values(i).WorkSocket = "FFF"
        Next

    Next
    stop1.Stop()
    Dim TotalMemory2 As Integer = GC.GetTotalMemory(False)
    MsgBox(TotalMemory2 - TotalMemory1)

    TotalMemory1 = GC.GetTotalMemory(False)
    Dim fff As Integer = GC.GetGeneration(ClientNetList)
    stop2.Start()
    For cnt As Integer = 1 To 1000000
        For Each ValueType As StateObject In ClientNetList.Values
            ValueType.WorkSocket = "FFF"
        Next
    Next
    stop2.Stop()

    Dim ffff As Integer = GC.GetGeneration(ClientNetList)
    TotalMemory2 = GC.GetTotalMemory(False)
    MsgBox(TotalMemory2 - TotalMemory1)

    Label1.Text = "i: " & stop1.ElapsedMilliseconds
    Label2.Text = "e: " & stop2.ElapsedMilliseconds
End Sub
役に立ちましたか?

解決

私のシステムでは、" for i = 1"ループは最初のテスト(プログラム実行のボタンの最初のクリック)で約20%高速でした。ただし、「for each」はループは、後続のテストで速かったです。 「for each」ループは少しメモリを消費しましたが、これは一時的なものであり、最終的にガベージコレクションになります。

「for each」の長所と短所および" for i ="ここで議論されています。それぞれが配列以外の構造で動作し、オブジェクトを使用可能にするため、それぞれに適しています。 " For i ="ループ内の配列項目の境界と順序を指定する利点があり、配列で発生する可能性があるバグを回避します。

Dim a(50) As Integer
Dim i As Integer
For Each i In a
  i = 22
  Next i

この例では、配列は22に初期化されません。変数iは配列要素の単なるコピーであり、iが22に割り当てられても元の配列要素は変更されません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top