summaryrefslogtreecommitdiff
path: root/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions
diff options
context:
space:
mode:
authorchai <215380520@qq.com>2024-06-03 10:15:45 +0800
committerchai <215380520@qq.com>2024-06-03 10:15:45 +0800
commitacea7b2e728787a0d83bbf83c8c1f042d2c32e7e (patch)
tree0bfec05c1ca2d71be2c337bcd110a0421f19318b /Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions
parent88febcb02bf127d961c6471d9e846c0e1315f5c3 (diff)
+ plugins project
Diffstat (limited to 'Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions')
-rw-r--r--Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/DifferentPoolSizeCollision.cs115
-rw-r--r--Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/MonoGame.Extended.Benchmarks.Collisions.csproj19
-rw-r--r--Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/Program.cs5
-rw-r--r--Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/SpaceAlgorithms.cs104
-rw-r--r--Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/Utils/Collider.cs29
5 files changed, 272 insertions, 0 deletions
diff --git a/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/DifferentPoolSizeCollision.cs b/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/DifferentPoolSizeCollision.cs
new file mode 100644
index 0000000..a4ac858
--- /dev/null
+++ b/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/DifferentPoolSizeCollision.cs
@@ -0,0 +1,115 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Engines;
+using Microsoft.Xna.Framework;
+using MonoGame.Extended.Collisions;
+using MonoGame.Extended.Collisions.Layers;
+using MonoGame.Extended.Collisions.QuadTree;
+
+namespace MonoGame.Extended.Benchmarks.Collisions;
+
+[SimpleJob(RunStrategy.ColdStart, launchCount:3)]
+public class DifferentPoolSizeCollision
+{
+ private const int COMPONENT_BOUNDARY_SIZE = 1000;
+
+ private readonly CollisionComponent _collisionComponent;
+ private readonly Random _random = new Random();
+ private readonly GameTime _gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromMilliseconds(16));
+
+ public DifferentPoolSizeCollision()
+ {
+ var size = new Size2(COMPONENT_BOUNDARY_SIZE, COMPONENT_BOUNDARY_SIZE);
+ _collisionComponent = new CollisionComponent(new RectangleF(Point2.Zero, size));
+ }
+
+ class Collider: ICollisionActor
+ {
+ public Collider(Point2 position)
+ {
+ Bounds = new RectangleF(position, new Size2(1, 1));
+ }
+
+ public IShapeF Bounds { get; set; }
+ public Vector2 Shift { get; set; }
+
+ public Point2 Position {
+ get => Bounds.Position;
+ set => Bounds.Position = value;
+ }
+
+ public void OnCollision(CollisionEventArgs collisionInfo)
+ {
+ }
+ }
+
+ [Params(100, 500, 1000)]
+ public int N { get; set; }
+
+
+ [Params(1, 2)]
+ public int LayersCount { get; set; }
+
+ public int UpdateCount { get; set; } = 100;
+
+
+ private List<Collider> _colliders = new();
+ private List<Layer> _layers = new();
+
+ [GlobalSetup]
+ public void GlobalSetup()
+ {
+ if (LayersCount > 1)
+ {
+ for (int i = 0; i < LayersCount; i++)
+ {
+ var size = new Size2(COMPONENT_BOUNDARY_SIZE, COMPONENT_BOUNDARY_SIZE);
+ var layer = new Layer(new SpatialHash(new Size2(5, 5)));//new QuadTreeSpace(new RectangleF(Point2.Zero, size)))));
+ _collisionComponent.Add(i.ToString(), layer);
+ _layers.Add(layer);
+ }
+ for (int i = 0; i < LayersCount - 1; i++)
+ _collisionComponent.AddCollisionBetweenLayer(_layers[i], _layers[i + 1]);
+
+ }
+
+ for (int i = 0; i < N; i++)
+ {
+ var layer = LayersCount == 1
+ ? _collisionComponent.Layers.First().Value
+ : _layers[i % LayersCount];
+
+ var collider = new Collider(new Point2(
+ _random.Next(COMPONENT_BOUNDARY_SIZE),
+ _random.Next(COMPONENT_BOUNDARY_SIZE)))
+ {
+ Shift = new Vector2(
+ _random.Next(4) - 2,
+ _random.Next(4) - 2),
+ };
+ _colliders.Add(collider);
+ layer.Space.Insert(collider);
+ }
+ }
+
+ [GlobalCleanup]
+ public void GlobalCleanup()
+ {
+ foreach (var collider in _colliders)
+ _collisionComponent.Remove(collider);
+ _colliders.Clear();
+ foreach (var layer in _layers)
+ _collisionComponent.Remove(layer: layer);
+ _layers.Clear();
+ }
+
+ [Benchmark]
+ public void Benchmark()
+ {
+ for (int i = 0; i < UpdateCount; i++)
+ {
+ foreach (var collider in _colliders)
+ collider.Position += collider.Shift;
+ //_collisionComponent.Update(_gameTime);
+ }
+ }
+}
diff --git a/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/MonoGame.Extended.Benchmarks.Collisions.csproj b/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/MonoGame.Extended.Benchmarks.Collisions.csproj
new file mode 100644
index 0000000..530bd13
--- /dev/null
+++ b/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/MonoGame.Extended.Benchmarks.Collisions.csproj
@@ -0,0 +1,19 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>net7.0</TargetFramework>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <Nullable>enable</Nullable>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="BenchmarkDotNet" Version="0.13.10" />
+ <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.1.303" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\src\cs\MonoGame.Extended.Collisions\MonoGame.Extended.Collisions.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/Program.cs b/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/Program.cs
new file mode 100644
index 0000000..647c934
--- /dev/null
+++ b/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/Program.cs
@@ -0,0 +1,5 @@
+using BenchmarkDotNet.Running;
+using MonoGame.Extended.Benchmarks.Collisions;
+
+//var summary = BenchmarkRunner.Run<DifferentPoolSizeCollision>();
+var summary = BenchmarkRunner.Run<SpaceAlgorithms>();
diff --git a/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/SpaceAlgorithms.cs b/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/SpaceAlgorithms.cs
new file mode 100644
index 0000000..7c82a32
--- /dev/null
+++ b/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/SpaceAlgorithms.cs
@@ -0,0 +1,104 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Engines;
+using Microsoft.Xna.Framework;
+using MonoGame.Extended.Benchmarks.Collisions.Utils;
+using MonoGame.Extended.Collisions;
+using MonoGame.Extended.Collisions.Layers;
+using MonoGame.Extended.Collisions.QuadTree;
+
+namespace MonoGame.Extended.Benchmarks.Collisions;
+
+[SimpleJob(RunStrategy.ColdStart, launchCount:10)]
+public class SpaceAlgorithms
+{
+ private const int COMPONENT_BOUNDARY_SIZE = 1000;
+
+ private readonly Random _random = new ();
+ private ISpaceAlgorithm _space;
+ private ICollisionActor _actor;
+ private RectangleF _bound;
+ private List<Collider> _colliders = new();
+
+ [Params(10, 100, 1000)]
+ public int N { get; set; }
+
+ [Params("SpatialHash", "QuadTree")]
+ public string Algorithm { get; set; }
+
+
+ [GlobalSetup]
+ public void GlobalSetup()
+ {
+ var size = new Size2(COMPONENT_BOUNDARY_SIZE, COMPONENT_BOUNDARY_SIZE);
+ _space = Algorithm switch
+ {
+ "SpatialHash" => new SpatialHash(new Size2(32, 32)),
+ "QuadTree" => new QuadTreeSpace(new RectangleF(Point2.Zero, size)),
+ _ => _space
+ };
+ for (int i = 0; i < N; i++)
+ {
+
+ var rect = GetRandomRectangleF();
+ var actor = new Collider(rect);
+ _colliders.Add(actor);
+ _space.Insert(actor);
+ }
+ }
+
+ [GlobalCleanup]
+ public void GlobalCleanup()
+ {
+ foreach (var collider in _colliders)
+ _space.Remove(collider);
+ _colliders.Clear();
+ }
+
+ [GlobalSetup(Targets = new[] { nameof(Insert), nameof(Remove) })]
+ public void ActorGlobalSetup()
+ {
+ GlobalSetup();
+ var rect = GetRandomRectangleF();
+ _actor = new Collider(rect);
+ }
+
+ [Benchmark]
+ public void Insert()
+ {
+ _space.Insert(_actor);
+ }
+
+ [Benchmark]
+ public void Remove()
+ {
+ _space.Remove(_actor);
+ }
+
+ [Benchmark]
+ public void Reset()
+ {
+ _space.Reset();
+ }
+
+ [GlobalSetup(Target = nameof(Query))]
+ public void QueryGlobalSetup()
+ {
+ GlobalSetup();
+ _bound = GetRandomRectangleF();
+ }
+
+ private RectangleF GetRandomRectangleF()
+ {
+ return new RectangleF(
+ _random.Next(COMPONENT_BOUNDARY_SIZE),
+ _random.Next(COMPONENT_BOUNDARY_SIZE),
+ _random.Next(32, 128),
+ _random.Next(32, 128));
+ }
+
+ [Benchmark]
+ public List<ICollisionActor> Query()
+ {
+ return _space.Query(_bound).ToList();
+ }
+}
diff --git a/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/Utils/Collider.cs b/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/Utils/Collider.cs
new file mode 100644
index 0000000..8005961
--- /dev/null
+++ b/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/Utils/Collider.cs
@@ -0,0 +1,29 @@
+using Microsoft.Xna.Framework;
+using MonoGame.Extended.Collisions;
+
+namespace MonoGame.Extended.Benchmarks.Collisions.Utils;
+
+public class Collider: ICollisionActor
+{
+ public Collider(Point2 position)
+ {
+ Bounds = new RectangleF(position, new Size2(1, 1));
+ }
+
+ public Collider(IShapeF shape)
+ {
+ Bounds = shape;
+ }
+
+ public IShapeF Bounds { get; set; }
+ public Vector2 Shift { get; set; }
+
+ public Point2 Position {
+ get => Bounds.Position;
+ set => Bounds.Position = value;
+ }
+
+ public void OnCollision(CollisionEventArgs collisionInfo)
+ {
+ }
+}