[Performance] Improvements to ScanCloseMobs logic (#4534)

* [Performance] Minor improvements to ScanCloseMobs

* Remove timer checks one level up to reduce branching

* Reserve memory in m_close_mobs to avoid frequent re-allocations if not already reserved.
This commit is contained in:
Chris Miles 2024-11-08 17:48:39 -06:00 committed by GitHub
parent 1ce51ca3b0
commit 0ea47fadee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 42 additions and 47 deletions

View File

@ -1578,7 +1578,10 @@ bool Bot::Process()
return false; return false;
} }
ScanCloseMobProcess(); if (m_scan_close_mobs_timer.Check()) {
entity_list.ScanCloseMobs(this);
}
SpellProcess(); SpellProcess();
if (tic_timer.Check()) { if (tic_timer.Check()) {

View File

@ -5013,7 +5013,11 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
SetMoving(!(cy == m_Position.y && cx == m_Position.x)); SetMoving(!(cy == m_Position.y && cx == m_Position.x));
CheckClientToNpcAggroTimer(); CheckClientToNpcAggroTimer();
if (m_mob_check_moving_timer.Check()) {
CheckScanCloseMobsMovingTimer(); CheckScanCloseMobsMovingTimer();
}
CheckSendBulkClientPositionUpdate(); CheckSendBulkClientPositionUpdate();
int32 new_animation = ppu->animation; int32 new_animation = ppu->animation;

View File

@ -281,7 +281,9 @@ bool Client::Process() {
} }
} }
ScanCloseMobProcess(); if (m_scan_close_mobs_timer.Check()) {
entity_list.ScanCloseMobs(this);
}
if (RuleB(Inventory, LazyLoadBank)) { if (RuleB(Inventory, LazyLoadBank)) {
// poll once a second to see if we are close to a banker and we haven't loaded the bank yet // poll once a second to see if we are close to a banker and we haven't loaded the bank yet

View File

@ -2947,6 +2947,12 @@ void EntityList::ScanCloseMobs(Mob *scanning_mob)
{ {
float scan_range = RuleI(Range, MobCloseScanDistance) * RuleI(Range, MobCloseScanDistance); float scan_range = RuleI(Range, MobCloseScanDistance) * RuleI(Range, MobCloseScanDistance);
// Reserve memory in m_close_mobs to avoid frequent re-allocations if not already reserved.
// Assuming mob_list.size() as an upper bound for reservation.
if (scanning_mob->m_close_mobs.bucket_count() < mob_list.size()) {
scanning_mob->m_close_mobs.reserve(mob_list.size());
}
scanning_mob->m_close_mobs.clear(); scanning_mob->m_close_mobs.clear();
for (auto &e : mob_list) { for (auto &e : mob_list) {
@ -2957,28 +2963,14 @@ void EntityList::ScanCloseMobs(Mob *scanning_mob)
float distance = DistanceSquared(scanning_mob->GetPosition(), mob->GetPosition()); float distance = DistanceSquared(scanning_mob->GetPosition(), mob->GetPosition());
if (distance <= scan_range || mob->GetAggroRange() >= scan_range) { if (distance <= scan_range || mob->GetAggroRange() >= scan_range) {
scanning_mob->m_close_mobs.emplace(std::pair<uint16, Mob *>(mob->GetID(), mob)); // add mob to scanning_mob's close list and vice versa
mob->m_close_mobs[scanning_mob->GetID()] = scanning_mob;
// add self to other mobs close list scanning_mob->m_close_mobs[mob->GetID()] = mob;
if (scanning_mob->GetID() > 0) {
bool has_mob = false;
for (auto &cm: mob->m_close_mobs) {
if (scanning_mob->GetID() == cm.first) {
has_mob = true;
break;
} }
} }
if (!has_mob) { LogAIScanClose(
mob->m_close_mobs.insert(std::pair<uint16, Mob *>(scanning_mob->GetID(), scanning_mob)); "[{}] Scanning close list > list_size [{}] moving [{}]",
}
}
}
}
LogAIScanCloseDetail(
"[{}] Scanning Close List | list_size [{}] moving [{}]",
scanning_mob->GetCleanName(), scanning_mob->GetCleanName(),
scanning_mob->m_close_mobs.size(), scanning_mob->m_close_mobs.size(),
scanning_mob->IsMoving() ? "true" : "false" scanning_mob->IsMoving() ? "true" : "false"

View File

@ -8584,6 +8584,7 @@ bool Mob::HasBotAttackFlag(Mob* tar) {
const uint16 scan_close_mobs_timer_moving = 6000; // 6 seconds const uint16 scan_close_mobs_timer_moving = 6000; // 6 seconds
const uint16 scan_close_mobs_timer_idle = 60000; // 60 seconds const uint16 scan_close_mobs_timer_idle = 60000; // 60 seconds
// If the moving timer triggers, lets see if we are moving or idle to restart the appropriate dynamic timer
void Mob::CheckScanCloseMobsMovingTimer() void Mob::CheckScanCloseMobsMovingTimer()
{ {
LogAIScanCloseDetail( LogAIScanCloseDetail(
@ -8593,9 +8594,6 @@ void Mob::CheckScanCloseMobsMovingTimer()
m_scan_close_mobs_timer.GetRemainingTime() m_scan_close_mobs_timer.GetRemainingTime()
); );
// If the moving timer triggers, lets see if we are moving or idle to restart the appropriate
// dynamic timer
if (m_mob_check_moving_timer.Check()) {
// If the mob is still moving, restart the moving timer // If the mob is still moving, restart the moving timer
if (moving) { if (moving) {
if (m_scan_close_mobs_timer.GetRemainingTime() > scan_close_mobs_timer_moving) { if (m_scan_close_mobs_timer.GetRemainingTime() > scan_close_mobs_timer_moving) {
@ -8611,14 +8609,6 @@ void Mob::CheckScanCloseMobsMovingTimer()
m_scan_close_mobs_timer.Disable(); m_scan_close_mobs_timer.Disable();
m_scan_close_mobs_timer.Start(scan_close_mobs_timer_idle); m_scan_close_mobs_timer.Start(scan_close_mobs_timer_idle);
} }
}
}
void Mob::ScanCloseMobProcess()
{
if (m_scan_close_mobs_timer.Check()) {
entity_list.ScanCloseMobs(this);
}
} }
std::unordered_map<uint16, Mob *> &Mob::GetCloseMobList(float distance) std::unordered_map<uint16, Mob *> &Mob::GetCloseMobList(float distance)

View File

@ -1488,7 +1488,6 @@ public:
bool IsCloseToBanker(); bool IsCloseToBanker();
void ScanCloseMobProcess();
std::unordered_map<uint16, Mob *> &GetCloseMobList(float distance = 0.0f); std::unordered_map<uint16, Mob *> &GetCloseMobList(float distance = 0.0f);
void CheckScanCloseMobsMovingTimer(); void CheckScanCloseMobsMovingTimer();

View File

@ -601,8 +601,13 @@ bool NPC::Process()
DepopSwarmPets(); DepopSwarmPets();
} }
ScanCloseMobProcess(); if (m_scan_close_mobs_timer.Check()) {
entity_list.ScanCloseMobs(this);
}
if (m_mob_check_moving_timer.Check()) {
CheckScanCloseMobsMovingTimer(); CheckScanCloseMobsMovingTimer();
}
if (hp_regen_per_second > 0 && hp_regen_per_second_timer.Check()) { if (hp_regen_per_second > 0 && hp_regen_per_second_timer.Check()) {
if (GetHP() < GetMaxHP()) { if (GetHP() < GetMaxHP()) {