SpaceAlgorithms.cs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. using BenchmarkDotNet.Attributes;
  2. using BenchmarkDotNet.Engines;
  3. using Microsoft.Xna.Framework;
  4. using MonoGame.Extended.Benchmarks.Collisions.Utils;
  5. using MonoGame.Extended.Collisions;
  6. using MonoGame.Extended.Collisions.Layers;
  7. using MonoGame.Extended.Collisions.QuadTree;
  8. namespace MonoGame.Extended.Benchmarks.Collisions;
  9. [SimpleJob(RunStrategy.ColdStart, launchCount:10)]
  10. public class SpaceAlgorithms
  11. {
  12. private const int COMPONENT_BOUNDARY_SIZE = 1000;
  13. private readonly Random _random = new ();
  14. private ISpaceAlgorithm _space;
  15. private ICollisionActor _actor;
  16. private RectangleF _bound;
  17. private List<Collider> _colliders = new();
  18. [Params(10, 100, 1000)]
  19. public int N { get; set; }
  20. [Params("SpatialHash", "QuadTree")]
  21. public string Algorithm { get; set; }
  22. [GlobalSetup]
  23. public void GlobalSetup()
  24. {
  25. var size = new Size2(COMPONENT_BOUNDARY_SIZE, COMPONENT_BOUNDARY_SIZE);
  26. _space = Algorithm switch
  27. {
  28. "SpatialHash" => new SpatialHash(new Size2(32, 32)),
  29. "QuadTree" => new QuadTreeSpace(new RectangleF(Point2.Zero, size)),
  30. _ => _space
  31. };
  32. for (int i = 0; i < N; i++)
  33. {
  34. var rect = GetRandomRectangleF();
  35. var actor = new Collider(rect);
  36. _colliders.Add(actor);
  37. _space.Insert(actor);
  38. }
  39. }
  40. [GlobalCleanup]
  41. public void GlobalCleanup()
  42. {
  43. foreach (var collider in _colliders)
  44. _space.Remove(collider);
  45. _colliders.Clear();
  46. }
  47. [GlobalSetup(Targets = new[] { nameof(Insert), nameof(Remove) })]
  48. public void ActorGlobalSetup()
  49. {
  50. GlobalSetup();
  51. var rect = GetRandomRectangleF();
  52. _actor = new Collider(rect);
  53. }
  54. [Benchmark]
  55. public void Insert()
  56. {
  57. _space.Insert(_actor);
  58. }
  59. [Benchmark]
  60. public void Remove()
  61. {
  62. _space.Remove(_actor);
  63. }
  64. [Benchmark]
  65. public void Reset()
  66. {
  67. _space.Reset();
  68. }
  69. [GlobalSetup(Target = nameof(Query))]
  70. public void QueryGlobalSetup()
  71. {
  72. GlobalSetup();
  73. _bound = GetRandomRectangleF();
  74. }
  75. private RectangleF GetRandomRectangleF()
  76. {
  77. return new RectangleF(
  78. _random.Next(COMPONENT_BOUNDARY_SIZE),
  79. _random.Next(COMPONENT_BOUNDARY_SIZE),
  80. _random.Next(32, 128),
  81. _random.Next(32, 128));
  82. }
  83. [Benchmark]
  84. public List<ICollisionActor> Query()
  85. {
  86. return _space.Query(_bound).ToList();
  87. }
  88. }