問題
在 Screeps 中,Memory 是很重要的存在刘急,它讓信息可以在Tick與Tick之間保存狀態(tài)矩父。但是每個(gè)Tick對(duì)Memory的第一次引用都會(huì)觸發(fā)Memory的反序列化,我們來看一下官方原文排霉。
可見,每次都進(jìn)行反序列化,對(duì)CPU的開銷是比較大的攻柠,官方也告訴我們球订,實(shí)際上使用RawMemory是一種更好的方式,但這需要我們自己去進(jìn)行設(shè)定瑰钮,并且這對(duì)很多人來說很難冒滩。
但接下來的方案您可以參考一下,在繼續(xù)說之前我需要問自己幾個(gè)問題浪谴。
注意:Memroy存在的意義是什么开睡?
它讓信息可以在Tick與Tick之間保存狀態(tài)
注意:還有什么可以跨Tick之間保存狀態(tài)?
沒錯(cuò),global苟耻,但是global會(huì)定時(shí)清空 這個(gè)問題在之后會(huì)得到解決
那么篇恒,我們只需要讓 RawMemory 做到Tick與Tick之間保持狀態(tài)就可以了,我們并不需要再去寫一個(gè)RawMemory序列/反序列模塊凶杖。
But, How?
- 我們讓序列化的數(shù)據(jù)胁艰,保存在 RawMemory0 (以下簡稱Raw0)中
- 讓global儲(chǔ)存我們的反序列化數(shù)據(jù),并建立Proxy監(jiān)聽
- 在Raw1(以下簡稱Cache)中記錄好每個(gè)tick對(duì)global的更改智蝠,當(dāng)變化時(shí)腾么,寫入到Cache
-
每當(dāng)global清空時(shí),立即從Raw0反序列化數(shù)據(jù)杈湾,通過合并Cache中的修改來還原數(shù)據(jù)的最后狀態(tài)并恢復(fù)數(shù)據(jù)到global
如此一來解虱,Cache中只會(huì)儲(chǔ)存被經(jīng)常修改的數(shù)據(jù),例如狀態(tài)機(jī)漆撞、坐標(biāo)位置殴泰、尋路緩存等小量動(dòng)態(tài)數(shù)據(jù),這部分?jǐn)?shù)據(jù)只有在Proxy監(jiān)聽到修改時(shí)會(huì)得到序列化與反序列化的同步更新叫挟,耗時(shí)取決于在一個(gè)global周期你做了多少事情艰匙;Raw0中的數(shù)據(jù)通常多的是大量靜態(tài)數(shù)據(jù),這部分?jǐn)?shù)據(jù)的序列化與反序列化頻率只取決于global被清空的頻率抹恳。
Absolutely员凝,我們在對(duì)每個(gè)Tick的修改進(jìn)行監(jiān)聽時(shí)使用到了Proxy,您當(dāng)然可以在Proxy中實(shí)現(xiàn)更加優(yōu)美的反序列化邏輯奋献。
Absolutely2健霹,您可以在Raw0與Cache(Raw1)合并時(shí)加入Raw2,Raw3等,來擴(kuò)容或者分類瓶蚂,并設(shè)置他們的合并邏輯糖埋。
關(guān)于global掛載這里有仙術(shù),可以參考
http://www.reibang.com/p/c6413d67893b