--------------------------------------------------------
直接对表进行访问与赋值
local vtbl = {} local t = {} --setmetatable(t, {__index = vtbl, -- __newindex = vtbl -- }) local t1 = os.clock() for i = 1, 10000000, 1 do t[1] = i end local t2 = os.clock() print(t2 - t1)
>lua -e "io.stdout:setvbuf 'no'" "main.lua"
0.263
>Exit code: 0
----------------------
通过设置元表为某table来实现访问与赋值:
local vtbl = {} local t = {} setmetatable(t, {__index = vtbl, __newindex = vtbl }) local t1 = os.clock() for i = 1, 10000000, 1 do t[1] = i end local t2 = os.clock() print(t2 - t1)
>lua -e "io.stdout:setvbuf 'no'" "main.lua"
0.435
>Exit code: 0
可以看到,多了一层表的访问,时间消耗增加一倍
------------------------
通过设置元表为某函数来实现访问与赋值:
local vtbl = {} local t = {} setmetatable(t, {__index = function(t, k) return vtbl[k] end, __newindex = function(t, k, v) vtbl[k] = v end, }) local t1 = os.clock() for i = 1, 10000000, 1 do t[1] = i end local t2 = os.clock() print(t2 - t1)
>lua -e "io.stdout:setvbuf 'no'" "main.lua"
0.981
>Exit code: 0
#########################
总结
#########################
结果显而易见,原方法为函数式写法时,最后的开销又增加了一倍,因为函数里本身就又有对表的访问与赋值,而调用函数又需要开销。
因此在设置元表时,如果仅仅只是把表t的访问或赋值转嫁到另外一个表vtbl中,建议采用:
setmetatable(t, {__index = vtbl, __newindex = vtbl})而不建议采用:
setmetatable(t, {__index = function(t, k) return vtbl[k] end, __newindex = function(t, k, v) vtbl[k] = v end,})