◆◆◆
簡單介紹
Lua作為一個極為精簡的嵌入型腳本語言,已經廣泛地用在了遊戲業。Lua的存在一般是兩種場合,一種用于實作遊戲上層業務邏輯,一種則利用了Lua語言本身靈活簡單的資料表達能力而被廣大程式員用于資料的存儲,也就是常說的配置檔案。
一般來說配置檔案的初始來源是策劃維護着的、有着一定格式限制的Excel表格,經由程式員提供的導出工具,把Excel的表格資料導出成為遊戲能直接讀取使用的Lua源碼。
這些源碼檔案以Lua table的形式存儲與Excel等價的資料,通常可以簡單把這個配置表看成是一組2維數組,轉換成配置就是一個key(Excel第一列)對應一組子資料(Excel中一行),那麼整個配置資料就是一個大表包含着若幹小表,如下:
原始配置表:

轉換成Lua後大緻是這樣:
如果配置檔案中的資料過大,或着是有備援的無用資料,那麼勢必會導緻輸出的Lua檔案過大,這将嚴重影響加載速度和增大記憶體占用量。本文将介紹一種消除配置檔案中備援資料,達到壓縮和優化資料存儲的方法。
優化思路
介紹該方法前,大家先來看看一般資料在哪些地方會有備援。由上面的示例圖我們可以清晰地看到資料的備援點:
大量的資料是重複的,或着是代表沒有意義的空值(比如0,[]等);
大量的中文字元串是需要遊戲後期做本地化處理的;
很多複合型資料(子表,數組)内容是一樣的;
搞清楚了資料備援的原因,我們就可以制定優化方案:
對于Excel中的一列,出現次數最多的值認定為預設值,然後把它從Lua表中剔除掉,然後利用metatable機制實作全局預設值存儲;
對于中文字元串,替換為一個唯一的id辨別,寫回到Lua表中,讀取的時候加上相應的查找替換;
對于一些複雜的子表或着數組,做唯一化替換處理,替換後寫回到原始資料中;
能看出來,上面的操作其實做的都是唯一化處理,是以有個要求就是整個Lua表的資料必須是隻讀的,如果不滿足以上條件,一切優化都是錯誤的。是以在最後我們需要把整個表改為隻讀,以保護資料不被錯誤篡改。
優化後變成了下面這樣:
看上去可讀性沒有原始的那麼高了,一些被多處引用的子表已經被替換成了一個變量,這些變量是以local的形式存儲在作用域的。由于Lua本身的一些限制,一個作用域内能夠存放的最大local變量的個數是200個(lparser.c #define MAXVARS 200),是以超過個數限制的多餘部分表會被放入一個臨時數組中,初始化的時候需要額外的查表,稍微多一些開銷,但可以接受。
歸納總結
一般來說配置表檔案優化後隻有之前不到一半的大小,大量的重複資料被優化掉了,極大地提升了加載時間和記憶體占用。
前後檔案對比如下:
最後說下宿主語言環境中,如果需要讀取Lua表中的子表資料,我們可以把該表的pointer拿出來作為鍵值,存放于查找表中,這樣宿主環境中也能讀取到一個唯一的數組,節約記憶體。
原文出處:侑虎科技
本文作者:admin
轉載請與作者聯系,同時請務必标明文章原始出處和原文連結及本聲明。