perf: switch 3 spawn queues from vector to deque

pendingPlayerSpawns_, deferredEquipmentQueue_, and
pendingGameObjectSpawns_ are consumed from the front via erase(begin()),
which is O(n) on vector (shifts all elements). With many spawns queued
(entering a city), this made the processing loop O(n²). deque supports
O(1) front erasure. pendingCreatureSpawns_ already used deque.
This commit is contained in:
Kelsi 2026-03-29 19:51:26 -07:00
parent 3b7ac068d2
commit f2237c5531

View file

@ -344,7 +344,8 @@ private:
std::unordered_map<uint64_t, OnlinePlayerAppearanceState> onlinePlayerAppearance_;
std::unordered_map<uint64_t, std::pair<std::array<uint32_t, 19>, std::array<uint8_t, 19>>> pendingOnlinePlayerEquipment_;
// Deferred equipment compositing queue — processes max 1 per frame to avoid stutter
std::vector<std::pair<uint64_t, std::pair<std::array<uint32_t, 19>, std::array<uint8_t, 19>>>> deferredEquipmentQueue_;
// deque: consumed from front in a loop; vector::erase(begin) would be O(n²).
std::deque<std::pair<uint64_t, std::pair<std::array<uint32_t, 19>, std::array<uint8_t, 19>>>> deferredEquipmentQueue_;
void processDeferredEquipmentQueue();
// Async equipment texture pre-decode: BLP decode on background thread, composite on main thread
struct PreparedEquipmentUpdate {
@ -402,7 +403,7 @@ private:
uint8_t facialFeatures;
float x, y, z, orientation;
};
std::vector<PendingPlayerSpawn> pendingPlayerSpawns_;
std::deque<PendingPlayerSpawn> pendingPlayerSpawns_;
std::unordered_set<uint64_t> pendingPlayerSpawnGuids_;
void processPlayerSpawnQueue();
std::unordered_set<uint64_t> creaturePermanentFailureGuids_;
@ -415,7 +416,7 @@ private:
float x, y, z, orientation;
float scale = 1.0f;
};
std::vector<PendingGameObjectSpawn> pendingGameObjectSpawns_;
std::deque<PendingGameObjectSpawn> pendingGameObjectSpawns_;
void processGameObjectSpawnQueue();
// Async WMO loading for game objects (file I/O + parse on background thread)