Vb.NET2D字典-非常慢
我需要创建一个2D字典/键值对。 我试过这样的东西Vb.NET2D字典-非常慢,vb.net,Vb.net,我需要创建一个2D字典/键值对。 我试过这样的东西 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
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秒。其他一切似乎都很好。是否有任何方法可以提高性能-可以代替使用字典 我建议您尝试使用
字典(元组的,字符串的,字符串的)
。也就是说,键是字符串对(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"))
当然,您可以定义自己的键类型(表示两个字符串的组合),如果它对您的口味来说过于通用
或者,您也可以只使用(可能)二维数组,但如果您的数据是(即,如果该二维矩阵中有许多空单元格),则可能会浪费大量空间;你将被迫使用数字索引而不是字符串
<强> P.S:实际上,考虑将字典值类型从<代码>字符串< /代码>更改为<代码>整数< /代码>;您的示例矩阵表明它只包含整数,因此将它们存储为字符串可能没有意义
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
我认为一个简单的结构就足够了
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)
我建议创建一个具有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
现在使用Tuple需要69秒,这是我提出的一个愚蠢的问题。谢谢你抽出时间。加上1.69秒(而不是70秒)并没有多大的改进…?我需要空值来满足我的需求,因为我需要创建一个类似于表的矩阵。当我使用字典(错误的逻辑)时,性能在68-71秒之间。元组连续69秒(逻辑相同错误)。我看不到Tuple有任何性能改进。但是你有没有尝试过字典和元组?无论如何,谢谢你的时间。这里发生了一些奇怪的事情。我运行了你的代码,代码占用了我的计算机大约85毫秒。您的代码运行速度慢了823倍。你还干什么?@Enigmativity,你是怎么尝试的?你能告诉我你是怎么做的吗。对我来说,其他一切都很好。除了创建一个空表需要超过68秒之外。不太清楚发生了什么。看看这段代码——它在LINQPad中运行大约85毫秒。它不会在dotnetfiddle上运行,因为它使用了太多的内存。哦,伙计……你的例子帮助我纠正了这个问题。你太棒了。作为回报,我会投票给你一些答案:)这有什么帮助?这基本上和你在问题中的代码一样。这是我提出的一个愚蠢的问题。谢谢你抽出时间。加1