Cache only unit paths in the pathfinder.

The path caching works on the assumption that the time saved from reusing a cached path outweights the cost of caching it in the first place.

For unit paths, this assumption holds. For path searchs, we spend more time caching them then we save when we get to reuse these cached paths. This is because they are reused less often, and calculating their key is more expensive in comparison.
This commit is contained in:
RoosterDragon
2015-08-21 21:27:20 +01:00
parent 0f9ef4036e
commit 774992c246
4 changed files with 7 additions and 64 deletions

View File

@@ -508,7 +508,7 @@
<Compile Include="Pathfinder\CellInfoLayerManager.cs" />
<Compile Include="Pathfinder\Constants.cs" />
<Compile Include="Pathfinder\PathGraph.cs" />
<Compile Include="Pathfinder\PathFinderCacheDecorator.cs" />
<Compile Include="Pathfinder\PathFinderUnitPathCacheDecorator.cs" />
<Compile Include="Pathfinder\PathCacheStorage.cs" />
<Compile Include="Traits\World\PathFinder.cs" />
<Compile Include="Traits\World\PathfinderDebugOverlay.cs" />

View File

@@ -18,8 +18,6 @@ namespace OpenRA.Mods.Common.Pathfinder
{
public interface IPathSearch
{
string Id { get; }
/// <summary>
/// The Graph used by the A*
/// </summary>
@@ -71,36 +69,6 @@ namespace OpenRA.Mods.Common.Pathfinder
{
public IGraph<CellInfo> Graph { get; set; }
// The Id of a Pathsearch is computed by its properties.
// So two PathSearch instances with the same parameters will
// Compute the same Id. This is used for caching purposes.
public string Id
{
get
{
if (string.IsNullOrEmpty(id))
{
var builder = new StringBuilder();
builder.Append(Graph.Actor.ActorID);
while (!startPoints.Empty)
{
var startpoint = startPoints.Pop();
builder.Append(startpoint.X);
builder.Append(startpoint.Y);
builder.Append(Graph[startpoint].EstimatedTotal);
}
builder.Append(Graph.InReverse);
if (Graph.IgnoredActor != null) builder.Append(Graph.IgnoredActor.ActorID);
builder.Append(Graph.LaneBias);
id = builder.ToString();
}
return id;
}
}
public IPriorityQueue<CPos> OpenQueue { get; protected set; }
public abstract IEnumerable<Pair<CPos, int>> Considered { get; }
@@ -108,7 +76,6 @@ namespace OpenRA.Mods.Common.Pathfinder
public Player Owner { get { return Graph.Actor.Owner; } }
public int MaxCost { get; protected set; }
public bool Debug { get; set; }
string id;
protected Func<CPos, int> heuristic;
protected Func<CPos, bool> isGoal;

View File

@@ -16,14 +16,14 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Pathfinder
{
/// <summary>
/// A decorator used to cache the pathfinder (Decorator design pattern)
/// A decorator used to cache FindUnitPath and FindUnitPathToRange (Decorator design pattern)
/// </summary>
public class PathFinderCacheDecorator : IPathFinder
public class PathFinderUnitPathCacheDecorator : IPathFinder
{
readonly IPathFinder pathFinder;
readonly ICacheStorage<List<CPos>> cacheStorage;
public PathFinderCacheDecorator(IPathFinder pathFinder, ICacheStorage<List<CPos>> cacheStorage)
public PathFinderUnitPathCacheDecorator(IPathFinder pathFinder, ICacheStorage<List<CPos>> cacheStorage)
{
this.pathFinder = pathFinder;
this.cacheStorage = cacheStorage;
@@ -68,37 +68,13 @@ namespace OpenRA.Mods.Common.Pathfinder
public List<CPos> FindPath(IPathSearch search)
{
using (new PerfSample("Pathfinder"))
{
var key = "FindPath" + search.Id;
var cachedPath = cacheStorage.Retrieve(key);
if (cachedPath != null)
return cachedPath;
var pb = pathFinder.FindPath(search);
cacheStorage.Store(key, pb);
return pb;
}
return pathFinder.FindPath(search);
}
public List<CPos> FindBidiPath(IPathSearch fromSrc, IPathSearch fromDest)
{
using (new PerfSample("Pathfinder"))
{
var key = "FindBidiPath" + fromSrc.Id + fromDest.Id;
var cachedPath = cacheStorage.Retrieve(key);
if (cachedPath != null)
return cachedPath;
var pb = pathFinder.FindBidiPath(fromSrc, fromDest);
cacheStorage.Store(key, pb);
return pb;
}
return pathFinder.FindBidiPath(fromSrc, fromDest);
}
}
}

View File

@@ -22,7 +22,7 @@ namespace OpenRA.Mods.Common.Traits
{
public object Create(ActorInitializer init)
{
return new PathFinderCacheDecorator(new PathFinder(init.World), new PathCacheStorage(init.World));
return new PathFinderUnitPathCacheDecorator(new PathFinder(init.World), new PathCacheStorage(init.World));
}
}