Skip to content

Commit c46aa8a

Browse files
committed
Improved AStar memory performance by avoiding excessive enumerator allocations
1 parent 75b5bbc commit c46aa8a

File tree

2 files changed

+8
-5
lines changed

2 files changed

+8
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Improvements
88
- Allow getting and setting TextureData by index
99
- Improved TextureExtensions.PremultipliedCopy memory performance
1010
- Improved the naming of SpriteBatchExtensions texture generation methods
11+
- Improved AStar memory performance by avoiding excessive enumerator allocations
1112

1213
Fixes
1314
- Fixed formatting codes at the start of strings not being added to the AllCodes collection

MLEM/Pathfinding/AStar.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Diagnostics;
4+
using System.Linq;
45

56
namespace MLEM.Pathfinding {
67
/// <summary>
@@ -86,11 +87,12 @@ public bool TryFindPath(T start, ICollection<T> goals, out Stack<T> path, out fl
8687
var tries = maxTries ?? this.DefaultMaxTries;
8788
var defCost = defaultCost ?? this.DefaultCost;
8889
var additional = additionalNeighbors ?? this.DefaultAdditionalNeighbors;
90+
var goalArray = goals as T[] ?? goals.ToArray();
8991

9092
var neighbors = new HashSet<T>();
9193
var open = new Dictionary<T, PathPoint<T>>();
9294
var closed = new Dictionary<T, PathPoint<T>>();
93-
open.Add(start, new PathPoint<T>(start, this.GetMinHeuristicDistance(start, goals), null, 0, defCost));
95+
open.Add(start, new PathPoint<T>(start, this.GetMinHeuristicDistance(start, goalArray), null, 0, defCost));
9496

9597
var count = 0;
9698
while (open.Count > 0) {
@@ -118,7 +120,7 @@ public bool TryFindPath(T start, ICollection<T> goals, out Stack<T> path, out fl
118120
foreach (var neighborPos in neighbors) {
119121
var cost = getCost(current.Pos, neighborPos);
120122
if (!float.IsPositiveInfinity(cost) && cost < float.MaxValue && !closed.ContainsKey(neighborPos)) {
121-
var neighbor = new PathPoint<T>(neighborPos, this.GetMinHeuristicDistance(neighborPos, goals), current, cost, defCost);
123+
var neighbor = new PathPoint<T>(neighborPos, this.GetMinHeuristicDistance(neighborPos, goalArray), current, cost, defCost);
122124
// check if we already have a waypoint at this location with a worse path
123125
if (open.TryGetValue(neighborPos, out var alreadyNeighbor)) {
124126
if (neighbor.G < alreadyNeighbor.G) {
@@ -160,10 +162,10 @@ public bool TryFindPath(T start, ICollection<T> goals, out Stack<T> path, out fl
160162
/// <param name="neighbors">The set to populate with neighbors.</param>
161163
protected abstract void CollectNeighbors(T position, ISet<T> neighbors);
162164

163-
private float GetMinHeuristicDistance(T start, IEnumerable<T> positions) {
165+
private float GetMinHeuristicDistance(T start, T[] positions) {
164166
var min = float.MaxValue;
165-
foreach (var position in positions)
166-
min = Math.Min(min, this.GetHeuristicDistance(start, position));
167+
for (var i = 0; i < positions.Length; i++)
168+
min = Math.Min(min, this.GetHeuristicDistance(start, positions[i]));
167169
return min;
168170
}
169171

0 commit comments

Comments
 (0)