mirror of
https://github.com/Stone-Red-Code/LargeGridPathfinding.git
synced 2026-09-04 00:56:10 +02:00
Batch agent path calculation for improved performance
This commit is contained in:
@@ -784,7 +784,8 @@ public class LargeGridPathfindingGame : Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Efficiently collect agents without paths (avoid LINQ allocation on hot path)
|
// Efficiently collect agents without paths (avoid LINQ allocation on hot path)
|
||||||
List<Agent> agentsRequirePathList = new List<Agent>(Math.Min(agents.Count, 16)); // pre-allocate reasonable capacity
|
List<Agent> agentsRequirePathList = new List<Agent>(agents.Count);
|
||||||
|
|
||||||
foreach (Agent agent in agents)
|
foreach (Agent agent in agents)
|
||||||
{
|
{
|
||||||
if (agent.Path is null)
|
if (agent.Path is null)
|
||||||
@@ -796,43 +797,46 @@ public class LargeGridPathfindingGame : Game
|
|||||||
if (agentsRequirePathList.Count != 0)
|
if (agentsRequirePathList.Count != 0)
|
||||||
{
|
{
|
||||||
int agentCount = agentsRequirePathList.Count;
|
int agentCount = agentsRequirePathList.Count;
|
||||||
|
int batchSize = Math.Max(64, agentCount / (Environment.ProcessorCount * 4));
|
||||||
|
|
||||||
ProgressTracker.ProgressData progressDataPaths = progressTracker.AddProgress($"Calculating {agentCount} paths", out IProgress<float> progress);
|
ProgressTracker.ProgressData progressDataPaths = progressTracker.AddProgress($"Calculating {agentCount} paths", out IProgress<float> progress);
|
||||||
|
|
||||||
// Use ParallelOptions to control concurrency
|
|
||||||
ParallelOptions parallelOptions = new ParallelOptions
|
ParallelOptions parallelOptions = new ParallelOptions
|
||||||
{
|
{
|
||||||
MaxDegreeOfParallelism = Environment.ProcessorCount
|
MaxDegreeOfParallelism = Environment.ProcessorCount
|
||||||
};
|
};
|
||||||
|
|
||||||
// Batch progress reporting every 100ms instead of modulo checks
|
|
||||||
long lastProgressReport = Environment.TickCount64;
|
long lastProgressReport = Environment.TickCount64;
|
||||||
int pathsCalculated = 0;
|
int pathsCalculated = 0;
|
||||||
|
|
||||||
_ = Parallel.ForEach(agentsRequirePathList, parallelOptions, agent =>
|
_ = Parallel.ForEach(Partitioner.Create(0, agentCount, batchSize), parallelOptions, range =>
|
||||||
{
|
|
||||||
// Calculate path once and reuse
|
|
||||||
List<Vector2>? path = CalculatePath(agent.GridPosition, agent.Destination) ?? CalculatePath();
|
|
||||||
agent.Path = path;
|
|
||||||
|
|
||||||
// Avoid repeated property access and null checks
|
|
||||||
if (path?.Count > 0)
|
|
||||||
{
|
{
|
||||||
agent.Position = path[0];
|
for (int i = range.Item1; i < range.Item2; i++)
|
||||||
agent.NextPosition = path.Count > 1 ? path[1] : path[0];
|
{
|
||||||
agent.Destination = new Point((int)path[^1].X, (int)path[^1].Y);
|
Agent agent = agentsRequirePathList[i];
|
||||||
}
|
|
||||||
|
|
||||||
// Batch progress updates to reduce lock contention
|
List<Vector2>? path = CalculatePath(agent.GridPosition, agent.Destination)
|
||||||
int local = Interlocked.Increment(ref pathsCalculated);
|
?? CalculatePath();
|
||||||
long now = Environment.TickCount64;
|
|
||||||
if (now - lastProgressReport > 100)
|
agent.Path = path;
|
||||||
{
|
|
||||||
progress.Report((float)local / agentCount);
|
if (path?.Count > 0)
|
||||||
lastProgressReport = now;
|
{
|
||||||
}
|
agent.Position = path[0];
|
||||||
});
|
agent.NextPosition = path.Count > 1 ? path[1] : path[0];
|
||||||
|
agent.Destination = new Point((int)path[^1].X, (int)path[^1].Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int local = Interlocked.Add(ref pathsCalculated, range.Item2 - range.Item1);
|
||||||
|
long now = Environment.TickCount64;
|
||||||
|
if (now - lastProgressReport > 100)
|
||||||
|
{
|
||||||
|
progress.Report((float)local / agentCount);
|
||||||
|
_ = Interlocked.Exchange(ref lastProgressReport, now);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Report final progress
|
|
||||||
progress.Report(1.0f);
|
progress.Report(1.0f);
|
||||||
progressTracker.RemoveProgress(progressDataPaths);
|
progressTracker.RemoveProgress(progressDataPaths);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user