Vb.Net 2D字典 - 非常慢

时间:2015-05-13 21:47:58

标签: vb.net

我需要创建一个2D字典/键值对。 我试过这样的事情。

enter image description here

Dim TwoDimData As New Dictionary(Of String, Dictionary(Of String, String))

'Create an empty table
For Each aid In AIDList   '(contains 15000 elements)
    TwoDimData.Add(aid, New Dictionary(Of String, String))
    For Each bid In BIDList   'contains 30 elements
        TwoDimData.Item(aid).Add(bid, "")
    Next
Next

'Later populate values.
[some code here to populate the table]

'Now access the value
'The idea is to access the info as given below (access by row name & col name)
 Msgbox TwoDimData.Item("A004").Item("B005")   ' should give the value of 2
 Msgbox TwoDimData.Item("A008").Item("B002")   ' should return empty string. No error

问题:

问题在于创建空表。创建具有空值的TwoDimData表需要70秒。其他一切似乎都没问题。有没有办法改善性能 - 可能不是使用字典?

3 个答案:

答案 0 :(得分:3)

我建议您尝试使用Dictionary(Of Tuple(Of String, String), String)。也就是说,键是字符串对(Tuple(Of String, String)),值是字符串。这看起来很符合您问题中的图表。

Dim matrix As New Dictionary(Of Tuple(Of String, String), String)

' Add a value to the matrix:
matrix.Add(Tuple.Create("A003", "B004"), "3")

' Retrieve a value from the matrix:
Dim valueAtA003B004 = matrix(Tuple.Create("A003", "B004"))

当然,如果Tuple(Of String, String)看起来过于通用,您可以定义自己的密钥类型(代表两个字符串的组合)。

或者,您也可以使用(可能是jagged)2D数组,但如果您的数据为sparse,则可能会浪费大量空间(即,如果2D中有许多空单元格)矩阵);并且你被迫使用数字索引而不是字符串。

P.S。:实际上,请考虑将字典值类型从String更改为Integer;你的示例矩阵表明它只包含整数,因此将它们存储为字符串可能没有意义。

P.P.S。: 为"空"添加值细胞到字典。那将是非常浪费的。而不是简单地从字典中检索值,而是检查字典是否包含密钥:

Dim valueA As String = ""  ' the default value
If matrix.TryGetValue(Tuple.Create("A007", "B002"), valueA) Then
    ' the given key was present, and the associated value has been retrieved
    …
End If

答案 1 :(得分:1)

我认为一个简单的结构就足够了吗?

Public Structure My2DItem
  Public Row As Integer
  Public Col As Integer
  Public Value As String
End Structure

Public My2DArray As Generic.List(Of My2DItem) = Nothing
Public Size As Integer
Public MaxRows As Integer
Public MaxCols As Integer
'
Sub Initialise2DArray()
'
Dim CountX As Integer
Dim CountY As Integer
Dim Item As My2DItem
'
  'initialise
  MaxRows = 15000
  MaxCols = 30
  Size = MaxRows * MaxCols
  My2DArray = New Generic.List(Of My2DItem)
  '   
  'Create an empty table
  For CountY = 1 To 15000
    For CountX = 1 To 30
      Item = New My2DItem
      Item.Row = CountY
      Item.Col = CountX
      Item.Value = "0"
      My2DArray.Add(Item)
      Item = Nothing
    Next
  Next
'
End Sub

要从数组中读取数据,

Function GetValue(Y As Integer, X As Integer) As String
'
Dim counter As Integer
'
GetValue = "Error!"
If My2DArray.Count > 0 Then
  For counter = 0 To My2DArray.Count - 1
    If My2DArray(counter).Row = Y Then
      If My2DArray(counter).Col = X Then
        GetValue = My2DArray(counter).Value
        Exit Function
      End If
    End If
  Next
End If
'
End Function

并阅读您的样本单元格A004 B005

MyStringValue = GetValue(4,5)

答案 2 :(得分:0)

我建议创建一个具有AID和BID属性的类,并将其用作要存储的值的基础

Public Class AIdBId
    Public Property AId As Integer
    Public Property BId As Integer
    Public Sub New(aId As Integer, bId As Integer)
        Me.AId = aid
        Me.BId = bid
    End Sub
End Class

请注意,我已经使用了整数,因为它似乎只是你需要的所有东西,并且使用字符串更有效

然后您可以在非零值处添加值:

'define your dictionary
Dim valueMatrix As New Dictionary(Of AIdBId, Integer)

'add your values
valueMatrix.Add(New AIdBId(1, 1), 1)
valueMatrix.Add(New AIdBId(2, 3), 1)
valueMatrix.Add(New AIdBId(4, 3), 3)
valueMatrix.Add(New AIdBId(5, 8), 8)

'check if a value exixts
Dim valueExixsts As Boolean = valueMatrix.ContainsKey(New AIdBId(9, 9))

'get a value
Dim i As Integer = valueMatrix(New AIdBId(4, 3))

所以你现在可以将这两个结合起来,如果有一个则返回值,否则返回零:

 Private Function GetValue(valuematrix As Dictionary(Of AIdBId, Integer), aId As Integer, bId As Integer) As Integer
    Dim xRef As New AIdBId(aId, bId)
    If valuematrix.ContainsKey(xRef) Then
        Return valuematrix(xRef)
    Else
        Return 0
    End If
End Function