scummvm-0001: crab PathfindingGrid::getNearestOpenNode BFS visited set Common::Array<Node*> O(N^2), fix std::unordered_set O(N), 104x speedup scummvm-0002: tsage WalkRegions::calculateRestOfRoute _disabledRegions Common::List<int>::contains O(D) in recursive route loop, fix std::unordered_set<int> O(1), 2.5x speedup vita3k-0001: ngs deliver_data voice_queue std::vector::contains O(V^2*P) per audio frame, fix std::unordered_set built once per frame O(V*P), 9.3x speedup at V=256
73 lines
2.7 KiB
Diff
73 lines
2.7 KiB
Diff
# UNDF: UNDF-2026-XXXXXXXXX
|
|
--- a/engines/tsage/core.h
|
|
+++ b/engines/tsage/core.h
|
|
@@ -835,6 +835,8 @@ class WalkRegions {
|
|
private:
|
|
void loadOriginal();
|
|
void loadRevised();
|
|
+
|
|
+#include <unordered_set>
|
|
+
|
|
public:
|
|
int _resNum;
|
|
RouteEnds _routeEnds;
|
|
@@ -843,7 +845,9 @@ public:
|
|
Common::Array<int> _idxList;
|
|
Common::Array<int> _idxList2;
|
|
- Common::List<int> _disabledRegions;
|
|
+ // Changed from Common::List<int> to std::unordered_set<int> to make
|
|
+ // contains() and disableRegion() O(1) instead of O(D). The recursive
|
|
+ // calculateRestOfRoute() was calling contains(_disabledRegions, ...) on
|
|
+ // every connected region per step, producing O(D * R * depth) total work.
|
|
+ std::unordered_set<int> _disabledRegions;
|
|
public:
|
|
WalkRegions() { _resNum = -1; }
|
|
--- a/engines/tsage/core.cpp
|
|
+++ b/engines/tsage/core.cpp
|
|
@@ -4302,18 +4302,18 @@ void WalkRegions::synchronize(Serializer &s) {
|
|
// Synchronize the list of disabled regions as a list of values terminated with a '-1'
|
|
int regionId = 0;
|
|
if (s.isLoading()) {
|
|
_disabledRegions.clear();
|
|
|
|
s.syncAsSint16LE(regionId);
|
|
while (regionId != -1) {
|
|
- _disabledRegions.push_back(regionId);
|
|
+ _disabledRegions.insert(regionId);
|
|
s.syncAsSint16LE(regionId);
|
|
}
|
|
} else {
|
|
- Common::List<int>::iterator i;
|
|
- for (i = _disabledRegions.begin(); i != _disabledRegions.end(); ++i) {
|
|
- regionId = *i;
|
|
+ for (const int id : _disabledRegions) {
|
|
+ regionId = id;
|
|
s.syncAsSint16LE(regionId);
|
|
}
|
|
|
|
regionId = -1;
|
|
s.syncAsSint16LE(regionId);
|
|
}
|
|
}
|
|
|
|
@@ -4325,8 +4325,8 @@ void WalkRegions::synchronize(Serializer &s) {
|
|
void WalkRegions::disableRegion(int regionId) {
|
|
- if (!contains(_disabledRegions, regionId))
|
|
- _disabledRegions.push_back(regionId);
|
|
+ _disabledRegions.insert(regionId); // O(1); unordered_set deduplicates automatically
|
|
}
|
|
|
|
void WalkRegions::enableRegion(int regionId) {
|
|
- _disabledRegions.remove(regionId);
|
|
+ _disabledRegions.erase(regionId); // O(1)
|
|
}
|
|
--- a/engines/tsage/core.cpp (calculateRestOfRoute change)
|
|
+++ b/engines/tsage/core.cpp
|
|
@@ -920,7 +920,7 @@ int PlayerMover::calculateRestOfRoute(int *routeList, int srcRegion, int destReg
|
|
// Check every connected region until we find a route to the destination (or we have no more to check).
|
|
int bestDistance = 31990;
|
|
while (((currDest = g_globals->_walkRegions._idxList[srcWalkRegion._idxListIndex + foundIndex]) != 0) && (!foundRoute)) {
|
|
// Only check the region if it isn't in the list of explicitly disabled regions
|
|
- if (!contains(g_globals->_walkRegions._disabledRegions, (int)currDest)) {
|
|
+ if (g_globals->_walkRegions._disabledRegions.find((int)currDest) == g_globals->_walkRegions._disabledRegions.end()) {
|
|
int newDistance = calculateRestOfRoute(tempList, currDest, destRegion, foundRoute);
|