隨著游戲的開發,項目的配置表數據越來越多,占用的內存越來越;配置表占用太大就會影響游戲加載速度,游戲流暢度的每一毫秒都是我們的必爭之路。
[1] = {DungeonID=10000, Dungeon= "王進打高俅", NextDungeonID=10100, BattleID= {10001, }, BattleTime=0, Quality=0, BackMusic= "BGM_Fight", },[2] = {DungeonID=10100, Dungeon= "魯提轄,拳打鎮關西", NextDungeonID=10200, BattleID= {10101, 10102, }, BattleTime=0, Quality=0, BackMusic= "BGM_Fight", },[3] = {DungeonID=10200, Dungeon= "五臺山,僧與俗的較量", NextDungeonID=10300, BattleID= {10201, 10202, 10203, 10204, 10205, 10206, 10207, 10208, }, BattleTime=0, Quality=0, BackMusic= "BGM_Fight", },
我們項目采用的配置表存儲方式是Lua表格,策劃配表用excel配置,然后使用網上的開源工具excel2lua導出lua表格,業務邏輯使用的時候直接import表就好了。在觀察了導出的lua表格后,我們整理出一堆待優化的問題:
1. 沒有意義的空值(比如0,[]等)
2. 重復數據
3. 默認值
4. 字段名優化
5. 客戶端、服務端表格分離
搞清楚了數據冗余的原因,我們就可以制定優化方案:
沒有意義的空值(比如0,[]等)
空的table:我們建了一張全局表GlobelEmptyTable = {},然后把這些空table都指向這個GlobelEmptyTable
重復數據
對于重復數據,我們在lua表新建一張duplication表,用來存放重復數據,然后把重復的數據,都指向這張表里面相應的重復的數據。
默認值
通過觀察可以發現其中有部分字段很容易重復,如:BattleTime、Quality等, 這些字段通常為枚舉或者有固定的分類,只有幾個不同的值,然而配置表中每個item
都需要為這些內容創建一個字段。
我們的優化方案是,利用lua的特性--原表(metatable),建一張defaultValues表,在導出的時候,選取出現次數最多的值作為每個字段的原表,存到defaultValues,然后剔除每行中與默認值相同的字段,從而節省內存。
local defaultValues = {Dungeon = "",Describe = "",PlayerLevel = 0,Name = "",NeedStar = 0,BackMusic = "BGM_Fight",PrizeInfo = 0,Crime = "",Num = 1,Place = "",BattleID = gConstEmptyTable,BackGround = "",NextDungeonID = 0,DungeonID = 0,ID = 0,
}dolocal base = {__index = defaultValues, --基類,默認值存取__newindex = function()--禁止寫入新的鍵值error("Attempt to modify read-only table")end}for k, v in pairs(DUNGEON_LIST) dosetmetatable(v, base)endbase.__metatable = false --不讓外面獲取到元表,防止被無意修改
end
字段名優化
熱心網友給我提出這種優化,但是這種類似CSV存儲格式,可想而知,內存肯定可以降低很多,我簡單實現了一下,比對了一下內存,差別還是很大的!!!但是這種存儲格式和默認值方案沖突,只能取舍,現在項目已經做完了,下個項目可以試一下這種方案。


local KeyMap = {costRes = 1,costTime = 2,troopsCount = 3,power = 4,model = 5,
}local BUILD101 = {[1] = {{}, 0, 2, 69, "castle1", },[2] = {{ 1001, 1782, 1002, 2430, 1003, 2430, 1004, 1458, }, 295, 2, 166, "castle1", },[3] = {{ 1001, 2673, 1002, 3645, 1003, 3645, 1004, 2187, }, 1080, 2, 302, "castle1", },
}dolocal base = {__index = function(table,key)local keyIndex = KeyMap[key]if not keyIndex thenprint("key not found: ",key)return nilendreturn table[keyIndex]end, --基類,默認值存取__newindex = function()--禁止寫入新的鍵值error("Attempt to modify read-only table")end}for k, v in pairs(BUILD101) dosetmetatable(v, base)endbase.__metatable = false --不讓外面獲取到元表,防止被無意修改
end
客戶端、服務端表格分離
服務器對于這么點內存,根本不會在意,但是客戶端大不一樣,是個精打細算的好媳婦,每一KB都要計較的,所以,我們設計一個參數來控制配置表導出對象,C:客戶端、S:服務端,在和策劃設計表的時候,告知哪些是客戶端需要的參數,導出的時候,按C、S導出2張表。
本文中使用的配置表優化工具源碼已經放在github,需要的朋友可以自取:)https://github.com/Aver58/Tools
使用元表優化 Lua 配置文件?www.orztu.com
