bugfix> vb.net > 投稿

私はいくつかのレガシーコードを持っています:

ひよこ( Dictionary )起動時に約350,000アイテム(ランタイム中に変更されません)。 dictPartsdictParts です 。

System.Collections.Generic.Dictionary(Of String, System.Data.DataRow) の各アイテムは dictParts です 。

なあ( System.Collections.Generic.KeyValuePair(Of String, System.Data.DataRow) )頻繁にアイテムが追加および削除されます(通常、配列内の2〜6アイテム)。 ArrayarrOut です arrOut のみを含む s。

配列が変更されるたびに、次のことを確認する必要があります。

  • 配列内のすべてのアイテムがインデックスに存在します
  • 配列内のアイテムの一部がインデックスに存在します

アレイが変更されるたびにインデックス350,000をループすると、パフォーマンスが大幅に低下し、LINQがサポートすることを期待していました。

私は次を試しました:

System.Array

エラーが発生し続ける: 'System.Collections.Generic.Dictionary string 型のオブジェクトをキャストできません 1 [System.Char] '。

誰かが私が間違っているところをアドバイスしてください。

Private Sub btnTest_Click(sender As System.Object, e As System.EventArgs) Handles btnTest.Click Dim dictParts = New Dictionary(Of Integer, String) _ From {{1, "AA-10-100"}, _ {2, "BB-20-100"}, _ {3, "CC-30-100"}, _ {4, "DD-40-100"}, _ {5, "EE-50-100"}} Dim arrOut() As String = {"AA-10-100", "BB-20-100", "CC-30-100"} 'Tried Dim allPartsExist As IEnumerable(Of String) = arrOut.ToString.All(dictParts) 'And this Dim allOfArrayInIndex As Object = arrOut.ToString.Intersect(dictParts).Count() = arrOut.ToString.Count End Sub
回答 2 件
  • 何かを学ぶために、@ emsimpson92によって提案されたハッシュセットを試しました。たぶんそれはあなたのために働くことができます。

    Imports System.Text
    Public Class HashSets
        Private shortList As New HashSet(Of String)
        Private longList As New HashSet(Of String)
        Private Sub HashSets_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            shortList.Add("AA-10-100")
            shortList.Add("BB-20-100")
            shortList.Add("DD-40-101")
            Dim dictParts As New Dictionary(Of Integer, String) _
            From {{1, "AA-10-100"},
                              {2, "BB-20-100"},
                              {3, "CC-30-100"},
                              {4, "DD-40-100"},
                              {5, "EE-50-100"}}
            For Each kv As KeyValuePair(Of Integer, String) In dictParts
                longList.Add(kv.Value)
            Next
        'Two alternative ways to fill the hashset
        '1. remove the New from the declaration
        'longList = New HashSet(Of String)(dictParts.Values)
        '2. Added in Framework 4.7.2
        'Enumerable.ToHashSet(Of TSource) Method (IEnumerable(Of TSource))
        'longList = dictParts.Values.ToHashSet()
        End Sub
        Private Sub CompareHashSets()
            Debug.Print($"The short list has {shortList.Count} elements")
            DisplaySet(shortList)
            Debug.Print($"The long list has {longList.Count}")
            shortList.ExceptWith(longList)
            Debug.Print($"The items missing from the longList {shortList.Count}")
            DisplaySet(shortList)
            'Immediate Window Results
            'The Short list has 3 elements
            '{ AA-10-100
            'BB-20 - 100
            'DD-40 - 101
            '}
            'The Long list has 5
            'The items missing from the longList 1
            '{ DD-40-101
            '}
        End Sub
        Private Shared Sub DisplaySet(ByVal coll As HashSet(Of String))
            Dim sb As New StringBuilder()
            sb.Append("{")
            For Each s As String In coll
                sb.AppendLine($" {s}")
            Next
            sb.Append("}")
            Debug.Print(sb.ToString)
        End Sub
        Private Sub btnCompare_Click(sender As Object, e As EventArgs) Handles btnCompare.Click
            CompareHashSets()
        End Sub
    End Class
    
    

    注:ハッシュセット内の要素は一意である必要があるため、ディクショナリに重複する値がある場合(ディクショナリキー、重複する値ではない)、ディクショナリからハッシュセットを満たすコードは機能しません。

  • HashSet でテストを実行する  元の Dictionary と  350,000個の値を含み、一致するアイテムが Dictionary の最後に追加されます 、 HashSet  15,000倍以上高速です。

    元の Dictionary に対するテスト :

    Dim AllInDict = arrOut.All(Function(a) dictParts.ContainsValue(a))
    Dim SomeInDict = arrOut.Any(Function(a) dictParts.ContainsValue(a))
    
    

    ザ・ HashSet  作成には4つの Dictionary の時間がかかります  検索するため、 Dictionary を変更しても価値はありません  4回の検索ごとよりも頻繁に。

    Dim hs = New HashSet(Of String)(dictParts.Values)
    
    

    その後、 HashSet を使用できます  メンバーシップをテストする。これは、 Dictionary 全体を検索するよりも少なくとも14,000倍高速です。  (もちろん、平均で約50%高速になります)。

    Dim AllInDict2 = arrOut.All(Function(a) hs.Contains(a))
    Dim SomeInDict2 = arrOut.Any(Function(a) hs.Contains(a))
    
    

あなたの答え