mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 15:30:43 +00:00
perf(pathfinding): replace array.shift() with index-based iteration for O(1) access (#2264)
## Description: Replaced Array.shift() in boat path iteration with an index-based loop to avoid O(n) shifts per step. This reduces per-move cost and keeps memory usage unchanged. I validated the change by running locally and confirming behaviour is unchanged. ### Summary This PR improves pathfinding performance by replacing Array.shift() with an index-based iteration to get the next boat position. Shifting the array for each move is O(n) per operation, whereas using an index is O(1). JavaScript does not free the memory of the shifted elements immediately, so there’s no memory benefit to shift() in this context. Using an index improves performance without additional memory cost. ### Testing & Caveats - I attempted to test the performance gain by increasing the trade cap to 5000, but on my system, neither method could be stressed enough to produce measurable differences. - I am unfamiliar with JavaScript profiling tools, so I do not have exact performance numbers. - Based on the change, there is no risk of decreased performance. - In my minor testing, the boat pathfinding felt faster when a single player was set to max speed as the game would slow down less. ### Notes - This is primarily an optimization for future scalability and clean performance improvements. - With this change, the max boat cap can potentially be increased. - The behavioural logic remains unchanged; the boats still navigate the same paths as before. ### Checklist - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced
This commit is contained in:
@@ -106,6 +106,7 @@ export class PathFinder {
|
||||
private curr: TileRef | null = null;
|
||||
private dst: TileRef | null = null;
|
||||
private path: TileRef[] | null = null;
|
||||
private path_idx: number = 0;
|
||||
private aStar: AStar<TileRef>;
|
||||
private computeFinished = true;
|
||||
|
||||
@@ -148,6 +149,7 @@ export class PathFinder {
|
||||
}
|
||||
|
||||
if (this.game.manhattanDist(curr, dst) < dist) {
|
||||
this.path = null;
|
||||
return { type: PathFindResultType.Completed, node: curr };
|
||||
}
|
||||
|
||||
@@ -156,11 +158,12 @@ export class PathFinder {
|
||||
this.curr = curr;
|
||||
this.dst = dst;
|
||||
this.path = null;
|
||||
this.path_idx = 0;
|
||||
this.aStar = this.newAStar(curr, dst);
|
||||
this.computeFinished = false;
|
||||
return this.nextTile(curr, dst);
|
||||
} else {
|
||||
const tile = this.path?.shift();
|
||||
const tile = this.path?.[this.path_idx++];
|
||||
if (tile === undefined) {
|
||||
throw new Error("missing tile");
|
||||
}
|
||||
@@ -172,8 +175,9 @@ export class PathFinder {
|
||||
case PathFindResultType.Completed:
|
||||
this.computeFinished = true;
|
||||
this.path = this.aStar.reconstructPath();
|
||||
// Remove the start tile
|
||||
this.path.shift();
|
||||
|
||||
// exclude first tile
|
||||
this.path_idx = 1;
|
||||
|
||||
return this.nextTile(curr, dst);
|
||||
case PathFindResultType.Pending:
|
||||
|
||||
Reference in New Issue
Block a user