Schneller vergleich zweier arrays

  • VB.NET

Es gibt 29 Antworten in diesem Thema. Der letzte Beitrag () ist von mcdt.

    Die Inhalte zweier Arrays ohne Schleife vergleichen zu wollen ist unmöglich.

    Bei häufig auftretenden unterschiedlichen Array-Längen ists natürlich eine effiziente Optimierung, zunächstmal die Array-Längen zu vergleichen, und nur bei gleicher Länge die einzelnen Elemente.

    Eine For-Schleife über zwei Arrays ist aber auch super-performant.
    Ich glaube nicht, dasses deswegen laggt, und wenndedas auch 1000 mal inne Sekunde aufrufst.
    Im allgemeinen laufen alle Update und Render funktionen derzeit über einen Timer:

    VB.NET-Quellcode

    1. Dim e As Date = Date.Now
    2. Dim lastCurrGameTimeMillis As Long = currGameTime.LastMilli
    3. currGameTime.LastDay = e.Day - startDate.Day
    4. currGameTime.LastHour = e.Hour + currGameTime.LastDay * 24 - startDate.Hour
    5. currGameTime.LastMinute = e.Minute + 60 * currGameTime.LastHour - startDate.Minute
    6. currGameTime.LastSec = e.Second + 60 * currGameTime.LastMinute - startDate.Second
    7. currGameTime.LastMilli = e.Millisecond + currGameTime.LastSec * 1000 - startDate.Millisecond
    8. currGameTime.ElapsedTime = currGameTime.LastMilli - lastCurrGameTimeMillis
    9. If currGameTime.LastFrameTicked + 1000 < currGameTime.LastMilli Then
    10. currGameTime.LastFrameTicked += 1000
    11. currGameTime.fps = ticks
    12. If showFPS Then
    13. Console.WriteLine(currGameTime.fps)
    14. End If
    15. ticks = 0
    16. End If
    17. update()
    18. ticks = ticks + 1


    Die Klasse GameTime enthält einige Infos, wie zum Beispiel die Zeit zwischen dem letzten Aufrufens, um das Spiel zu Timen.
    Bei dem Spielfeld (100x150) wird jedes einzelne Element geupdated. Die Bilduings Beispielsweise:

    VB.NET-Quellcode

    1. Public Overridable Sub Produce(ByVal t As GameTime, ByVal rnd As Random)
    2. 59: If Main.selectedGameMode = Main.GameMode.FreeBuild Then
    3. Exit Sub
    4. End If
    5. Try REM HABITABLE
    6. Dim tmp_s As String = (Int(inhabitant + 1).ToString & "/" & maxInhabits.ToString & " - " & Me.Parent.Parent.Location.X.ToString & ":" & Me.Parent.Parent.Location.Y.ToString)
    7. countToNextUpdate += t.ElapsedTime
    8. countToNextMinute += t.ElapsedTime
    9. 60: If countToNextMinute >= 60000 Then
    10. countToNextMinute = 0
    11. If isHabitable() Then
    12. If inhabitant = 0 Then
    13. GoTo 61
    14. End If
    15. Dim needs1 As Inventory
    16. needs1 = needs
    17. For i As Integer = 0 To inhabitant - 2
    18. needs1.add(needs)
    19. Next
    20. If needs1 < Main.userInv Then
    21. happiness += happiness ^ -1 * 20
    22. For i As Integer = 0 To inhabitant - 1
    23. Main.userInv.subtract(needs)
    24. Next
    25. Else
    26. happiness -= happiness ^ 2 / 1000
    27. End If
    28. Main.userInv.Thaler += Main.tax * inhabitant * (((happiness + 10) ^ 2 / 100) / 100)
    29. Else
    30. If type = buildings.Mine Then
    31. mineLength -= 10
    32. End If
    33. Main.userInv.Thaler -= salary * worker
    34. End If
    35. End If
    36. 61:
    37. If isHabitable() Then
    38. If countToNextUpdate >= produceEvery Then
    39. countToNextUpdate = 0
    40. 'Main.userInv.Thaler += Main.tax * inhabitant * (((happiness + 10) ^ 2 / 100) / 100)
    41. If inhabitant <= maxInhabits - 1 Then
    42. MoveIn(rnd)
    43. End If
    44. End If
    45. Else
    46. If countToNextUpdate >= produceEvery Then
    47. countToNextUpdate = 0
    48. Try
    49. If needs < Main.userInv Then
    50. Exit Sub
    51. End If
    52. Main.userInv.subtract(needs)
    53. Catch
    54. If Not needs Is Nothing Then
    55. Exit Sub
    56. End If
    57. End Try
    58. If Not type = buildings.Mine Then
    59. For i As Integer = 0 To worker - 1
    60. Main.userInv.add(produces)
    61. Next
    62. Else
    63. If mineLength <= 0 Then
    64. currMinepart = MinePart.null
    65. End If
    66. If currMinepart = MinePart.null Then
    67. Exit Sub
    68. End If
    69. Dim pr As String = Int(currMinepart).ToString
    70. Dim pro As New List(Of Integer)
    71. For i As Integer = 0 To Main.userInv.Items.Count - 1
    72. pro.Add(0)
    73. Next
    74. For i As Integer = 0 To 3
    75. If pr(0) = "0" Then
    76. Exit For
    77. End If
    78. Try
    79. Select i
    80. Case 0
    81. pro(Inventory.getItemIDByName("Stone")) = Int(pr(i).ToString) * 10
    82. Case 1
    83. pro(Inventory.getItemIDByName("Coal")) = Int(pr(i).ToString)
    84. Case 2
    85. pro(Inventory.getItemIDByName("Iron")) = Int(pr(i).ToString)
    86. Case 3
    87. pro(Inventory.getItemIDByName("Gold")) = Int(pr(i).ToString)
    88. End Select
    89. Catch ex As Exception
    90. Continue For
    91. End Try
    92. Next
    93. Dim prod As New Inventory(pro.ToArray)
    94. For i As Integer = 0 To worker - 1
    95. Main.userInv.add(prod)
    96. Next
    97. End If
    98. End If
    99. End If
    100. REM END HABITABLE
    101. Catch ex As Exception
    102. End Try
    103. End Sub

    Dieser Code bringt das Spiel zum Absturz.
    Am meisten Zeit benötigt er wiederum im Inventar:

    VB.NET-Quellcode

    1. Public Items() As Integer = {0, 0, 0, 0, 0, 0, 0, 0}
    2. REM REM REM REM REM REM REM REM REM ## 0 # 1 # # 2 # 3 # 4 # 5 # 6 # 7
    3. Public Shared ItemNames() As String = {"Wood", "Stone", "Wheat", "Flour", "Bread", "", "", ""}
    4. Enum Item As Integer
    5. Wood = 0
    6. Stone = 1
    7. Wheat = 2
    8. Flour = 3
    9. End Enum
    10. Public Shared Function getItemIDByName(ByVal s As String) As Integer
    11. Dim l As New List(Of String)(ItemNames)
    12. l = ItemNames.ToList
    13. For i As Integer = 0 To l.Count
    14. If l(i) = s Then
    15. Return i
    16. End If
    17. Next
    18. Return -1
    19. End Function
    20. Public Shared Operator <(ByVal i1 As Inventory, ByVal i2 As Inventory)
    21. Try
    22. For i As Integer = 0 To i1.Items.Count - 1
    23. If i1.Items(i) >= i2.Items(i) Then
    24. Return False
    25. End If
    26. Next
    27. Return True
    28. Catch
    29. Return False
    30. End Try
    31. End Operator
    32. Public Shared Operator >(ByVal i1 As Inventory, ByVal i2 As Inventory)
    33. Try
    34. For i As Integer = 0 To i1.Items.Count - 1
    35. If i1.Items(i) <= i2.Items(i) Then
    36. Return False
    37. End If
    38. Next
    39. Return True
    40. Catch
    41. Return False
    42. End Try
    43. End Operator
    44. Public Shared Operator =(ByVal i1 As Inventory, ByVal i2 As Inventory)
    45. Try
    46. For i As Integer = 0 To i1.Items.Count - 1
    47. If i1.Items(i) <> i2.Items(i) Then
    48. Return False
    49. End If
    50. Next
    51. Return True
    52. Catch
    53. Return False
    54. End Try
    55. End Operator
    56. Public Shared Operator <>(ByVal i1 As Inventory, ByVal i2 As Inventory)
    57. Return Not i1 = i2
    58. End Operator
    59. Public Shared Operator >=(ByVal i1 As Inventory, ByVal i2 As Inventory)
    60. Return i1 > i2 Or i1 = i2
    61. End Operator
    62. Public Shared Operator <=(ByVal i1 As Inventory, ByVal i2 As Inventory)
    63. Return i1 < i2 Or i1 = i2
    64. End Operator
    Ich denke ich habe eine möglichkeit gefunden das ganze system schneller laufen zu lassen. Statt jedes einzelne Building zu updaten, update ich nur 1 Manager klasse, die Infos über die Buildings gespeichert hat. Demnach sind das statt 15 Buildings, die das gleiche ausführen, nur 1 Manager klasse, die zwar öfters updated, dafür aber bei einer höheren anzahl von Buildings deutlich schneller laufen sollte. Manchmal muss man halt mal eine Nacht drüber schlafen.

    Trotzdem danke für eure hilfe.