From 3e4b5b366077c5455f70d61aa466c27e27f57a37 Mon Sep 17 00:00:00 2001 From: vis2k Date: Sat, 17 Sep 2022 16:11:56 +0800 Subject: [PATCH] perf: Grid2D initial capacity to avoid warmup allocations --- .../SpatialHashing/Grid2D.cs | 36 +++++++++++-------- .../SpatialHashingInterestManagement.cs | 3 +- Assets/Mirror/Tests/Editor/Grid2DTests.cs | 2 +- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/Assets/Mirror/Components/InterestManagement/SpatialHashing/Grid2D.cs b/Assets/Mirror/Components/InterestManagement/SpatialHashing/Grid2D.cs index f4702ece5..41417cd04 100644 --- a/Assets/Mirror/Components/InterestManagement/SpatialHashing/Grid2D.cs +++ b/Assets/Mirror/Components/InterestManagement/SpatialHashing/Grid2D.cs @@ -18,22 +18,27 @@ public struct Grid2D // => makes the code a lot easier too // => this is FINE because in the worst case, every grid position in the // game world is filled with a player anyway! - readonly Dictionary> grid = - new Dictionary>(); + readonly Dictionary> grid; // cache a 9 neighbor grid of vector2 offsets so we can use them more easily - readonly Vector2Int[] neighbourOffsets = + readonly Vector2Int[] neighbourOffsets; + + public Grid2D(int initialCapacity) { - Vector2Int.up, - Vector2Int.up + Vector2Int.left, - Vector2Int.up + Vector2Int.right, - Vector2Int.left, - Vector2Int.zero, - Vector2Int.right, - Vector2Int.down, - Vector2Int.down + Vector2Int.left, - Vector2Int.down + Vector2Int.right - }; + grid = new Dictionary>(initialCapacity); + + neighbourOffsets = new[] { + Vector2Int.up, + Vector2Int.up + Vector2Int.left, + Vector2Int.up + Vector2Int.right, + Vector2Int.left, + Vector2Int.zero, + Vector2Int.right, + Vector2Int.down, + Vector2Int.down + Vector2Int.left, + Vector2Int.down + Vector2Int.right + }; + } // helper function so we can add an entry without worrying public void Add(Vector2Int position, T value) @@ -41,7 +46,10 @@ public void Add(Vector2Int position, T value) // initialize set in grid if it's not in there yet if (!grid.TryGetValue(position, out HashSet hashSet)) { - hashSet = new HashSet(); + // each grid entry may hold hundreds of entities. + // let's create the HashSet with a large initial capacity + // in order to avoid resizing & allocations. + hashSet = new HashSet(128); grid[position] = hashSet; } diff --git a/Assets/Mirror/Components/InterestManagement/SpatialHashing/SpatialHashingInterestManagement.cs b/Assets/Mirror/Components/InterestManagement/SpatialHashing/SpatialHashingInterestManagement.cs index 2f78e7254..298603497 100644 --- a/Assets/Mirror/Components/InterestManagement/SpatialHashing/SpatialHashingInterestManagement.cs +++ b/Assets/Mirror/Components/InterestManagement/SpatialHashing/SpatialHashingInterestManagement.cs @@ -40,7 +40,8 @@ public enum CheckMethod public bool showSlider; // the grid - Grid2D grid = new Grid2D(); + // begin with a large capacity to avoid resizing & allocations. + Grid2D grid = new Grid2D(1024); // project 3d world position to grid position Vector2Int ProjectToGrid(Vector3 position) => diff --git a/Assets/Mirror/Tests/Editor/Grid2DTests.cs b/Assets/Mirror/Tests/Editor/Grid2DTests.cs index 34c3b88b6..c445d1a38 100644 --- a/Assets/Mirror/Tests/Editor/Grid2DTests.cs +++ b/Assets/Mirror/Tests/Editor/Grid2DTests.cs @@ -11,7 +11,7 @@ public class Grid2DTests [SetUp] public void SetUp() { - grid = new Grid2D(); + grid = new Grid2D(10); } [Test]