Screeps游戏 Memory仙术

大群正在打yoner,附上应景图片

image.png

什么是Memory仙术呢?

众所周知Memory是需要反序列化的,反序列化需要cpu
具体文档:https://docs.screeps.com/global-objects.html#Memory-object

Memory等价于:

Memory = JSON.parse(RawMemory.get()); 
RawMemory.set(JSON.stringify(Memory));

而游戏默认在第一次调用Memroy会清理反序列化,换句话说,这个过程是在本地执行的,源码:
https://github.com/screeps/engine/blob/78d980e50821ea9956d940408b733c44fc9d94ed/src/game/game.js#L478

image.png

禁止反序列化:

因为memory是每次都要系列化和反序列化,而实际上我们只要第一次序列化就够了,所以我们完全可以存储在global里面,在代码初始化的时候调用即可:

_global_memory = JSON.parse(RawMemory.get());

然后重新挂载在global.memory

delete global.Memory;
global.Memory = _global_memory;

这时可以省掉cpu反序化的消耗

内存自动保存

观察源码:

Object.defineProperty(runCodeCache[userId].globals, 'Memory', {
  configurable: true,
  enumerable: true,
  value: runCodeCache[userId].memory._parsed
});
_.extend(runCodeCache[userId].globals, {
  RawMemory: runCodeCache[userId].memory,
  console: runCodeCache[userId].fakeConsole
});

易得:

'Memory' == RawMemory._parsed

所以如果我们需要让代码自动序列化:

RawMemory._parsed = Memory

即可省掉序列化cpu的消耗

RawMemory.set(JSON.stringify(Memory));

Memroy 仙术:

整理一下代码


let _global_memory = undefined

let main = function(){
    if(_global_memory){
        delete global.Memory;
        global.Memory = _global_memory;
        RawMemory._parsed = global.Memory;
    }else{
        _global_memory = global.Memory
    }
    ......

性能:

50K的 memroy相当于消耗0.7-0.8cpu
经过Memory仙术后
对于shard3,你可以节省大概 1cpu左右
四舍五入等于半个房间

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容