openxcom-0001: AIModule _reachable/_reachableWithAttack std::vector<int> with std::find() inside AI loops (setupAmbush, setupEscape, selectPointNearTarget, findFirePoint). O(N*R) per alien turn where N = nodes checked, R = reachable tiles (~500 on typical map). Fix: std::unordered_set<int> for O(1) lookup. MEDIUM-HIGH, 7.6x. openxcom-0002: SavedGame::isResearched linear scan of _discovered vector O(D) per call, called O(R*4) times from getAvailableResearchProjects per base. Also unlocked vector with std::find O(R*U). Fix: parallel unordered_set<string> for O(1) lookup. MEDIUM, 4.5x. MOAD-0002 (Intertangle): CLEAN, typical game state architecture MOAD-0003 (Leaked Context): CLEAN, single-threaded game MOAD-0004 (Logged Secret): CLEAN, no credentials MOAD-0005 (Thundering Herd): CLEAN, no concurrent caching
72 lines
3.7 KiB
Diff
72 lines
3.7 KiB
Diff
--- a/src/Battlescape/AIModule.h
|
|
+++ b/src/Battlescape/AIModule.h
|
|
@@ -20,6 +20,7 @@
|
|
#include <yaml-cpp/yaml.h>
|
|
#include "BattlescapeGame.h"
|
|
#include "Position.h"
|
|
+#include <unordered_set>
|
|
#include "../Savegame/BattleUnit.h"
|
|
#include <vector>
|
|
|
|
@@ -50,7 +51,7 @@
|
|
bool _traceAI, _didPsi;
|
|
int _AIMode, _intelligence, _closestDist;
|
|
Node *_fromNode, *_toNode;
|
|
- std::vector<int> _reachable, _reachableWithAttack, _wasHitBy;
|
|
+ std::unordered_set<int> _reachable, _reachableWithAttack;
|
|
+ std::vector<int> _wasHitBy;
|
|
BattleActionType _reserve;
|
|
UnitFaction _targetFaction;
|
|
public:
|
|
--- a/src/Battlescape/AIModule.cpp
|
|
+++ b/src/Battlescape/AIModule.cpp
|
|
@@ -150,7 +150,10 @@
|
|
_attackAction->actor = _unit;
|
|
_attackAction->weapon = action->weapon;
|
|
_attackAction->number = action->number;
|
|
_escapeAction->number = action->number;
|
|
- _reachable = _save->getPathfinding()->findReachable(_unit, _unit->getTimeUnits());
|
|
+ {
|
|
+ std::vector<int> rv = _save->getPathfinding()->findReachable(_unit, _unit->getTimeUnits());
|
|
+ _reachable = std::unordered_set<int>(rv.begin(), rv.end());
|
|
+ }
|
|
_wasHitBy.clear();
|
|
|
|
@@ -197,7 +200,8 @@
|
|
_blaster = true;
|
|
- _reachableWithAttack = _save->getPathfinding()->findReachable(_unit, _unit->getTimeUnits() - _unit->getActionTUs(BA_AIMEDSHOT, action->weapon));
|
|
+ { std::vector<int> rv = _save->getPathfinding()->findReachable(_unit, _unit->getTimeUnits() - _unit->getActionTUs(BA_AIMEDSHOT, action->weapon));
|
|
+ _reachableWithAttack = std::unordered_set<int>(rv.begin(), rv.end()); }
|
|
}
|
|
else
|
|
{
|
|
_rifle = true;
|
|
- _reachableWithAttack = _save->getPathfinding()->findReachable(_unit, _unit->getTimeUnits() - _unit->getActionTUs(BA_SNAPSHOT, action->weapon));
|
|
+ { std::vector<int> rv = _save->getPathfinding()->findReachable(_unit, _unit->getTimeUnits() - _unit->getActionTUs(BA_SNAPSHOT, action->weapon));
|
|
+ _reachableWithAttack = std::unordered_set<int>(rv.begin(), rv.end()); }
|
|
}
|
|
@@ -208,7 +212,8 @@
|
|
_melee = true;
|
|
- _reachableWithAttack = _save->getPathfinding()->findReachable(_unit, _unit->getTimeUnits() - _unit->getActionTUs(BA_HIT, action->weapon));
|
|
+ { std::vector<int> rv = _save->getPathfinding()->findReachable(_unit, _unit->getTimeUnits() - _unit->getActionTUs(BA_HIT, action->weapon));
|
|
+ _reachableWithAttack = std::unordered_set<int>(rv.begin(), rv.end()); }
|
|
}
|
|
|
|
// All std::find() calls on _reachable and _reachableWithAttack become .count():
|
|
|
|
@@ -612,1 +617,1 @@
|
|
- std::find(_reachableWithAttack.begin(), _reachableWithAttack.end(), _save->getTileIndex(pos)) == _reachableWithAttack.end())
|
|
+ _reachableWithAttack.count(_save->getTileIndex(pos)) == 0)
|
|
@@ -902,1 +907,1 @@
|
|
- if (std::find(_reachable.begin(), _reachable.end(), _save->getTileIndex(_escapeAction->target)) == _reachable.end())
|
|
+ if (_reachable.count(_save->getTileIndex(_escapeAction->target)) == 0)
|
|
@@ -1165,1 +1170,1 @@
|
|
- if (_save->getTile(checkPath) == 0 || std::find(_reachable.begin(), _reachable.end(), _save->getTileIndex(checkPath)) == _reachable.end())
|
|
+ if (_save->getTile(checkPath) == 0 || _reachable.count(_save->getTileIndex(checkPath)) == 0)
|
|
@@ -1462,1 +1467,1 @@
|
|
- std::find(_reachableWithAttack.begin(), _reachableWithAttack.end(), _save->getTileIndex(pos)) == _reachableWithAttack.end())
|
|
+ _reachableWithAttack.count(_save->getTileIndex(pos)) == 0)
|
|
@@ -2096,1 +2101,2 @@
|
|
- _reachableWithAttack = _save->getPathfinding()->findReachable(_unit, _unit->getTimeUnits() - _unit->getActionTUs(BA_HIT, meleeWeapon));
|
|
+ { std::vector<int> rv = _save->getPathfinding()->findReachable(_unit, _unit->getTimeUnits() - _unit->getActionTUs(BA_HIT, meleeWeapon));
|
|
+ _reachableWithAttack = std::unordered_set<int>(rv.begin(), rv.end()); }
|