您的位置:首页 > 编程语言 > Lua

编写高效Lua代码的方法 - 总结

2011-11-12 13:58 459 查看
基础
1 尽量使用local
使用变量的效率:local > upvalue > global
local变量存放在栈中,upvalue存放在链表中,global变量存放在全局的表中。
例子:
使用local

function Add()
local x, y
return x + y
end


使用upvalue

local x, y
function Add()
return x + y
end


使用global

function Add()
return x + y
end


2 尽量不使用loadstring等函数来动态调用代码
编译工作是很繁重的,动态调用代码时Lua虚拟机需要动态地编译Lua代码,效率很低。


3 减少表的插入次数
Lua中的表由一个数组和一个哈希表组成,每一次从表中插入数据,Lua都会重新计算每个元素新的存放位置,导致插入的效率很低。

local a = {}
a[1] = 1 -- 重新哈希,数组部分大小为1
a[2] = 2 -- 重新哈希,数组部分大小为2
a[3] = 3 -- 重新哈希,数组部分大小为4


以上的代码产生三次重新哈希计算以及三次数组部分扩容,相比以下代码只执行了一次哈希和扩容。

local a = {true, true, true} -- 重新哈希,数组部分大小为4
a[1] = 1
a[2] = 2
a[3] = 3


4 不要试图通过删除表元素来节省内存空间
对表中的元素赋nil值不会导致表元素被删除,但是在插入新元素时,表会根据现有的非nil元素的数量来更改表的大小。

字符串
5 避免字符串连接
Lua在虚拟机内部对于相同的字符串只保留一份copy,保存在一个哈希表中,字符串变量保存这个copy的引用。这种实现机制导致Lua中字符串的查找和比较效率比较高,创建的效率比较低。

减少
6 减少表的创建

polyline = { { x = 10.3, y = 98.5 },
{ x = 10.3, y = 18.3 },
{ x = 15.0, y = 98.5 },
...
}


同样表达点的序列的表,以上代码每个点都创建一个表,相比以下代码只创建了两个表。

polyline = { x = { 10.3, 10.3, 15.0, ...},
y = { 98.5, 18.3, 98.5, ...}
}


7 避免不必要的创建
Lua虚拟机每执行到local就创建一个变量,执行到function就创建一个闭包。参考 Lua 5.0实现 4 函数和闭包
重用
8 重用表是一个比较有效的手段

local t = {}
for i = 1970, 2000 do
t[i] = os.time({year = i, month = 6, day = 14})
end


以下是与之等价的代码,但是重用了表:

local t = {}
local aux = {year = nil, month = 6, day = 14}
for i = 1970, 2000 do
aux.year = i
t[i] = os.time(aux)
end


9 使用记忆化方法

function memoize (f)
local mem = {} --记忆化的表,存储每一个输入的计算结果
setmetatable(mem, {__mode = "kv"}) -- 定义成弱表
return function (x) -- 这个函数就是记忆化的f
local r = mem[x]
if r == nil then -- 如果没有对应的计算结果
r = f(x) -- 调用f计算
mem[x] = r -- 保存在记忆化表中
end
return r -- 已经计算过,直接返回结果
end
end


假如有以下函数:

function fab(x)
if x == 1 or x == 2 then
return 1
end
return fab(x-1) + fab(x-2)
end


对比不使用记忆化方法和记忆化方法:
fab(35) -- 执行8s
fab = memoize(fab)
fab(35) -- 不超过1s

相关链接
编写高效Lua代码的方法 - 1 - 基本知识
编写高效Lua代码的方法 - 2 - 表相关
编写高效Lua代码的方法 - 3 - 字符串

编写高效Lua代码的方法 - 4 - 减少,重用,回收
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: