Mirroar / hivemind

Fully automated open source AI core for the game screeps. Also usable as an opponent on private servers.
MIT License
29 stars 11 forks source link

Memory profiling #22

Open Mirroar opened 3 years ago

Mirroar commented 3 years ago

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.

Mirroar commented 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.

Mirroar commented 3 years ago

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.