Open Mirroar opened 3 years ago
Currently, room memory makes up more than half of total memory consumption on the live server for me. Here's a dump using the code from snippets.js on Memory.rooms (I've moved the biggest perpetrators to the top):
{
"intel": 368198,
"remoteHarvesting": 300314,
"roomPlanner": 269338,
"storage": 388,
"lastClaim": 3047,
"enemies": 18279,
"sources": 42005,
"minerals": 11759,
"boostManager": 14074,
"labsLastChecked": 1272,
"canPerformReactions": 756,
"observerChecked": 192,
"nukerChecked": 192,
"powerSpawnChecked": 192,
"structureCache": 28548,
"controllerContainer": 2729,
"controllerLink": 2771,
"roleplay": 1998,
"labs": 11928,
"currentReaction": 228,
"spawnQueue": 934,
"throttleOffset": 222,
"isEvacuating": 5,
"bestReaction": 4,
"storageLink": 1887,
"isClearingTerminal": 5,
"observerId": 338,
"nukerId": 338,
"powerSpawnId": 338,
"observeTargets": 74,
"manager": 1042,
"abandonedResources": 6302,
"fillTerminal": 25,
"fillTerminalAmount": 23,
"inactiveStructures": 2
}
This shows pretty clearly where we can optimize.
intel
a while back, reducing the amount of Pathfinder.CostMatrix serializations that are being saved.remoteHarvesting
, we already use the better position path serialization that saves a lot of memory. However it seems there is some outdated info saved in there, for sources that haven't been harvested in a long time. Maybe we could check remoteHarvesting[sourcePos].cachedPath.lastCalculated
and remove the info when it's too old.roomPlanner
, there isn't really anything we can get rid of. Our best bet might be refactoring the locations to not be stored in object keys, but instead make it a list of unique room positions that we can put into our path serialization mentioned above. This will be especially helpful on roads and ramparts. We could even extend utilities.encodePosition
and utilities.decodePosition
to optionally take a room name in cases where the room for a position is fixed. That way the room name doesn't show up in every single encoded position, saving 6 bytes each. This change comes with extra CPU cost, as usual. But it should mostly affect the room planner and room manager, which don't run too often. It also kind of affects the room defense manager, but that needs a list of positions anyway, so we're golden.The same scan on Memory.creeps shows that obviously the pathfinder takes up most memory:
{
"cachedPath": 84423,
"_move": 44599,
"body": 15094,
"go": 10751,
"singleRoom": 1776,
"role": 6045,
"_tO": 3591,
"repairing": 159,
"moveBlocked": 2542,
"sourceTarget": 2158,
"order": 8188,
"storage": 3829,
"source": 3641,
"delivering": 1094,
"energyPickupTarget": 3302,
"upgrading": 87,
"sourceRoom": 72,
"targetRoom": 72,
"dismantling": 4,
"fixedMineralSource": 52,
"harvesting": 656,
"travelTimer": 2844,
"fixedSource": 1950,
"deliverTarget": 778,
"target": 568,
"pathTarget": 120,
"initialized": 36,
"nextRoom": 136,
"isHealer": 16,
"mission": 288,
"needsBoosting": 20
}
It might be worth investigating if in some cases we can get rid of either cachedPath
, _move
or go
. However, saving about 15KB by no longer caching a creep's body composition in memory seems pretty worthwile to me. We need to check where that is used, and if removing it is much of a performance hit. I think it'll probably be fine.
Memory is starting to become a bottleneck. We somewhat fixed that by limiting our Scout Radius. But saving on memory might allow for more flexibility in the future.
For that we can add a little memory profiler to see where the most memory is used. We can aggregate similar memory objects (like rooms, creeps, ...) to get a good overall picture. From there we can decide what to optimize, or where to use memory segments.