Reputation: 611
I have a list of objects that looks like this:
Public Class LineItem
Public Property Name As String
Public Property Weight As Int32
Public Property Expression As String
End Class
Private _lineItems As New List(Of LineItem)
I randomly select one item as so:
Public Function SelectItem(ByVal name As String) As LineItem
Dim items As List(Of LineItem) = CType(Rules.Where(Function(li As LineItem) li.Name = name.Remove("[", "]")).ToList, List(Of LineItem))
Dim totalWeight As Int32 = items.Sum(Function(li As LineItem) li.Weight)
If totalWeight > 0 Then
Dim sum As Int32 = 0
Dim index As Int32 = (BaseGrammar.Random.Next Mod totalWeight) + 1
For Each item As LineItem In items
sum += CInt(item.Weight)
If sum >= index Then
Return item
End If
Next
End If
Return Nothing
End Function
While this works fine for small lists, when the lists get large, obviously it is terribly inefficient. Is there a structure or method that I'm missing that could make this more efficient?
Upvotes: 0
Views: 100
Reputation: 250
I think you function is fine, but did you considered that you code goes through the loop 3 times .. first to take out characters, than find sum, and then capture the subset of items. Maybe if you redo your code by removing initial Linq, you can make a regular loop in which you can fix Name property and sum up Weight. That will cut your time by 33%
Upvotes: 1