id
col1
col2
col3
id1value1_1
value1_2
value1_3
id2value2_1
value2_2
value2_3
id3value3_1
value3_2
value3_3
以乙個m行n列的**為例
儲存結構
dictionary>
第一層: key:行id,value:行資料
第二層: key: 列名稱 value: 該行該列值
占用空間
在lua中,空表占用56位元組,資料分list部分和hash部分
list部分每個資料佔16位元組
hash部分每個資料佔32位元組
lua中table的list和hash部分實際空間大小和分配是個複雜的問題
一般來說list部分大小為2的冪,填充率不低於1/2,
不在list部分的放入hash部分
hash部分大小原則同list
乙個m行n列的**
以行儲存,乙個m大小hash表,m個n大小的hash表
占用大小,(56 + 32m) + m * (56 + 32n)
資料讀取
以讀取一行配置,使用5個列資料為例
根據id獲得table(執行1次)
根據col_name從table中獲取資料(執行5次)
儲存結構
dictionary
key:行id,value: 行索引
dictionary
key:列名稱 value:該列值組成的陣列,按行索引排序
占用空間
以列儲存,乙個m大小的hash表,1個n大小的hash表,n個m大小的list表
占用大小, 56 + 32m + 56 + 32n + n*(56+16m)
資料讀取
根據id獲得index索引,生成閉包,返回帶元方法的空表 (執行1次)
讀取屬性時觸發__index,根據col_name獲得資料列,根據index獲取資料(執行5次)
function getconfig(id)
local index = id_tab[id]
return setmetatable({},)
end
占用空間
以行儲存-以列儲存= 16mn + 56m – 88n – 56
一般行數m遠大於列數n,故列儲存占用空間小很多
資料讀取
以行儲存簡單直接,沒有gc
以列儲存需要建立空表,原表,閉包,索引次數也更多
專案看重記憶體占用,故選取列儲存
預設值在很多時候,同列資料會有重複值
如果出現次數超過一半,就成為該列預設值
去掉與預設值相同的行索引,list表轉換為hash表
hash元素占用空間是list兩倍,故一半是個分割點
當然getconfig也就更複雜一點
重複表專案中很多列都是陣列甚至二維陣列,即lua的表
如果每個值都指向各自的表,白白浪費空間
只有同列才最可能出現重複值,這也是列儲存思路的優勢,當然行儲存也可以這麼做
將出現次數超過某個值(與錶行數相關)的值提取成local變數,可大幅節省空間
檔案結構
local dup_col2_val1 =
return ,
col1 = , [6] = },
col2 = , dup_col2_val1, dup_col2_val1, , , dup_col2_val1, },
...}
local a =
local b =
a是長度8的list表
b卻是大小8的hash表
不知是我測試錯誤還是另有原因
每次讀取屬性都要觸發__index
有預設值時大概率索引index返回null,判空後取預設值
如果是大量反覆取屬性,比如排序,效能可能造成瓶頸
如果有這種情況,可以在返回的空表中快取屬性
lua配置表儲存優化方案
lua 效能剖析
yaml做配置檔案
yaml是 yaml ain t a markup language yaml不是一種置標語言 的遞迴縮寫。可以做多種用途 指令碼語言,序列化,配置檔案 我們常見的是config.yaml做配置檔案 可以看出,同乙個縮排屬於同乙個級別的,可以理解為和window的資料夾一樣,當前面有 就是乙個陣列。...
使用 rapidxml 做配置檔案
對於配置檔案,一般會選用 ini,xml 等等的配置格式。如何快速高效的從檔案內讀取自己想要的資訊是每個做配置檔案想要達到的效果。對以小型開發我們並不用時用到 msxml 這種重量級的解析器。那樣會給自己添麻煩的。這裡我推薦大家使用 rapidxml 之前使用 tinyxml 感覺還可以。後看了 r...
lua與C 互動 配置檔案
背景 我們可以將一些常常改動的資料寫到lua檔案中去,就不用每次在程式更改了乙個小資料的時候就要重新編譯整個專案。我們可以將這個工程裡面寫好解析指令碼的功能就可以啦 例項 我們可以在config.lua檔案中寫到。config.lua檔案 width 1000 height 6000然後在c 程式裡...