問題
在 Screeps 中,Memory 是很重要的存在,它讓信息可以在Tick與Tick之間保存狀態(tài)。但是每個Tick對Memory的第一次引用都會觸發(fā)Memory的反序列化,我們來看一下官方原文。

可見,每次都進(jìn)行反序列化,對CPU的開銷是比較大的,官方也告訴我們,實際上使用RawMemory是一種更好的方式,但這需要我們自己去進(jìn)行設(shè)定,并且這對很多人來說很難。
但接下來的方案您可以參考一下,在繼續(xù)說之前我需要問自己幾個問題。
注意:Memroy存在的意義是什么?
它讓信息可以在Tick與Tick之間保存狀態(tài)
注意:還有什么可以跨Tick之間保存狀態(tài)?
沒錯,global,但是global會定時清空 這個問題在之后會得到解決
那么,我們只需要讓 RawMemory 做到Tick與Tick之間保持狀態(tài)就可以了,我們并不需要再去寫一個RawMemory序列/反序列模塊。
But, How?
- 我們讓序列化的數(shù)據(jù),保存在 RawMemory0 (以下簡稱Raw0)中
- 讓global儲存我們的反序列化數(shù)據(jù),并建立Proxy監(jiān)聽
- 在Raw1(以下簡稱Cache)中記錄好每個tick對global的更改,當(dāng)變化時,寫入到Cache
-
每當(dāng)global清空時,立即從Raw0反序列化數(shù)據(jù),通過合并Cache中的修改來還原數(shù)據(jù)的最后狀態(tài)并恢復(fù)數(shù)據(jù)到global
如此一來,Cache中只會儲存被經(jīng)常修改的數(shù)據(jù),例如狀態(tài)機(jī)、坐標(biāo)位置、尋路緩存等小量動態(tài)數(shù)據(jù),這部分?jǐn)?shù)據(jù)只有在Proxy監(jiān)聽到修改時會得到序列化與反序列化的同步更新,耗時取決于在一個global周期你做了多少事情;Raw0中的數(shù)據(jù)通常多的是大量靜態(tài)數(shù)據(jù),這部分?jǐn)?shù)據(jù)的序列化與反序列化頻率只取決于global被清空的頻率。
Absolutely,我們在對每個Tick的修改進(jìn)行監(jiān)聽時使用到了Proxy,您當(dāng)然可以在Proxy中實現(xiàn)更加優(yōu)美的反序列化邏輯。
Absolutely2,您可以在Raw0與Cache(Raw1)合并時加入Raw2,Raw3等,來擴(kuò)容或者分類,并設(shè)置他們的合并邏輯。
關(guān)于global掛載這里有仙術(shù),可以參考
http://www.itdecent.cn/p/c6413d67893b
