Name: screeps-profiler
Owner: screepers
Description: This is a profiler designed for use in the game of screeps.
Created: 2015-12-28 06:27:25.0
Updated: 2018-01-08 06:06:54.0
Pushed: 2017-10-14 13:39:28.0
Homepage: null
Size: 42
Language: JavaScript
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
The Screeps Profiler is a library that helps to understand where your CPU is being spent in the game of Screeps.
It works by monkey patching functions on the Global game object prototypes, with a function that record how long each function takes. The primary benefit of using this profiler is that you can get a clear picture of where your CPU is being used over time, and optimize some of the heavier functions. While it works best for players that heavily employ prototypes in their code, it should work to some degree for all players.
You have two options for installing this script. You can either use npm and a compiler like webpack, or you can copy/paste the screeps-profiler.js
file and use the provided screeps require function.
Your main.js will will need to be configured like so.
ny modules that you use that modify the game's prototypes should be require'd
efore you require the profiler.
t profiler = require('screeps-profiler');
his line monkey patches the global prototypes.
iler.enable();
le.exports.loop = function() {
ofiler.wrap(function() {
// Main.js logic should go here.
;
You can make use of the profiler via the Screeps console.
.profiler.profile(ticks, [functionFilter]);
.profiler.stream(ticks, [functionFilter]);
.profiler.email(ticks, [functionFilter]);
.profiler.background([functionFilter]);
utput current profile data.
.profiler.output([lineCount]);
eset the profiler, disabling any profiling in the process.
.profiler.reset();
.profiler.restart();
Note: It can take up to 30 ticks if you're using module.exports.loop
for these commands to work without issue.
profile
- Will run for the given number of ticks then will output the gathered information to the console.
stream
- Will run for the given number of ticks, and will output the gathered information each tick to the console. The can sometimes be useful for seeing spikes in performance.
email
- This will run for the given number of ticks, and will email the output to your registered Screeps email address. Very useful for long running profiles.
background
- This will run indefinitely, and will only output data when the output
console command is run. Very useful for long running profiles with lots of function calls.
output
- Print a report based on the current tick. The profiler will continue to operate normally. This is currently the only way to get data from the background
profile.
reset
- Stops the profiler and resets its memory. This is currently the only way to stop a background
profile.
restart
- Restarts the profiler using the same options previously used to start it.
In each case, ticks
controls how long the profiler should run before stopping, and the optional functionFilter
parameter will limit the scope of the profiler to a specific function.
Below is a sample output of Game.profiler.profile(1000)
s time avg function
12293.9, 6.147 Room.work
4 6025.0, 0.552 Creep.work
3534.5, 1.767 Spawn.work
0 1949.3, 0.028 Structure.work
1733.8, 0.612 Creep.moveTo
1093.7, 0.293 Creep.moveToAndHarvest
886.0, 0.534 Creep.takeEnergyFrom
871.9, 0.103 Room.createConstructionSite
852.7, 0.244 Creep.harvest
745.8, 0.765 Creep.deliverEnergyTo
741.1, 0.283 Room.needsCouriers
700.5, 2.520 RoomPosition.findPathTo
673.6, 2.423 Room.findPath
2 575.4, 0.027 Spawn.availableEnergy
535.1, 0.191 Room.getStorage
511.7, 0.243 Creep.move
487.1, 0.266 Creep.moveByPath
483.9, 0.336 Creep.moveToAndUpgrade
6 454.5, 0.017 Room.find
443.1, 0.104 Room.droppedControllerEnergy
15.43 Total: 15425.31 Ticks: 1000 Est. Bucket (20 limit): 5055
Seeing that Spawn.work
is high, we might run Game.profiler.profile(200, 'Spawn.work')
to see what about Spawn.work
is taking so long. From that we would get:
s time avg function
137.7, 2.221 Spawn.work
25.8, 0.251 Room.needsCouriers
23.9, 0.583 Room.needsUpgraders
18.6, 0.452 Room.needsHarvesters
17.6, 0.429 Room.getSourcesNeedingHarvesters
16.1, 0.154 Room.getStorage
14.9, 0.027 Spawn.availableEnergy
12.1, 0.035 Room.find
8.4, 0.135 Room.harvesterCount
8.3, 0.174 Spawn.extend
7.9, 0.037 Room.getExtensions
7.3, 0.178 Room.droppedControllerEnergy
7.1, 0.069 Room.courierCount
7.1, 0.115 Room.getHarvesters
6.5, 0.158 Room.needsBuilders
6.1, 0.509 Spawn.buildBuilder
5.8, 0.094 Room.setupFlags
5.6, 0.055 Room.getCouriers
5.0, 0.330 Room.upgraderWorkParts
4.8, 0.116 Room.builderCount
13.54 Total: 2707.90 Ticks: 200 Est. Bucket (20 limit): 1774
Note: Each function recorded here was part of a call stack with Spawn.work
at the root.
The profiler automatically registers many of the built in functions in Screeps, but not every player extends the provided prototypes. The profiler supports arbitrary registration of objects and functions as well, but takes a bit more work to setup.
In order to do it, you'll need to import the profiler wherever you want to register a function, then call registerClass
, registerObject
, or registerFN
.
Example:
t profiler = require('screeps-profiler');
s SuperOmegaCreep {
rk() {
hiddenManagersPlaybook.delegate();
ach of the functions on this class will be replaced with a profiler wrapper. The second parameter
s a required label.
iler.registerClass(SuperOmegaCreep, 'SuperOmegaCreep');
t gameHandlerObject = {
ndleGame: () => {
// do some work.
ach of the functions on this object will be replaced with a profiler wrapper. The second parameter
s a required label.
iler.registerObject(gameHandlerObject, 'gameHandlerObject');
tion getAllScouts() {
turn Object.keys(Game.creeps).filter(creepName => {
const creep = Game.creeps[creepName];
return creep.memory.role === 'scout';
;
e sure to reassign the function, we can't alter functions that are passed.
llScouts = profiler.registerFN(getAllScouts, 'mySemiOptionalName');
Note: The second param is optional if you pass a named function function x() {}
, but required if you pass an anonymous function var x = function(){}
.
There is some work to setting up the functions for profiling. While this work is kept to a minimum when the profiler is not in use, it may be beneficial to comment out or remove the profiler.enable()
call when you know you aren't going to be using it. This will revert the monkey patched functions to their original functions.