编写高效Lua代码的方法 - 总结
2011-11-12 13:58
459 查看
基础
1 尽量使用local
使用变量的效率:local > upvalue > global
local变量存放在栈中,upvalue存放在链表中,global变量存放在全局的表中。
例子:
使用local
使用upvalue
使用global
2 尽量不使用loadstring等函数来动态调用代码
编译工作是很繁重的,动态调用代码时Lua虚拟机需要动态地编译Lua代码,效率很低。
表
3 减少表的插入次数
Lua中的表由一个数组和一个哈希表组成,每一次从表中插入数据,Lua都会重新计算每个元素新的存放位置,导致插入的效率很低。
以上的代码产生三次重新哈希计算以及三次数组部分扩容,相比以下代码只执行了一次哈希和扩容。
4 不要试图通过删除表元素来节省内存空间
对表中的元素赋nil值不会导致表元素被删除,但是在插入新元素时,表会根据现有的非nil元素的数量来更改表的大小。
字符串
5 避免字符串连接
Lua在虚拟机内部对于相同的字符串只保留一份copy,保存在一个哈希表中,字符串变量保存这个copy的引用。这种实现机制导致Lua中字符串的查找和比较效率比较高,创建的效率比较低。
减少
6 减少表的创建
同样表达点的序列的表,以上代码每个点都创建一个表,相比以下代码只创建了两个表。
7 避免不必要的创建
Lua虚拟机每执行到local就创建一个变量,执行到function就创建一个闭包。参考 Lua 5.0实现 4 函数和闭包
重用
8 重用表是一个比较有效的手段
以下是与之等价的代码,但是重用了表:
9 使用记忆化方法
假如有以下函数:
对比不使用记忆化方法和记忆化方法:
fab(35) -- 执行8s
fab = memoize(fab)
fab(35) -- 不超过1s
相关链接
编写高效Lua代码的方法 - 1 - 基本知识
编写高效Lua代码的方法 - 2 - 表相关
编写高效Lua代码的方法 - 3 - 字符串
编写高效Lua代码的方法 - 4 - 减少,重用,回收
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 - 减少,重用,回收
相关文章推荐
- 编写高效Lua代码的方法
- 编写高效Lua代码的方法 - 1 - 基本知识
- 编写高效Lua代码的方法 - 2 - 表相关
- 编写高效Lua代码的方法 - 3 - 字符串
- 编写高效Lua代码的方法(整理)
- 编写高效Lua代码的方法(整理)
- 编写高效Lua代码的方法 - 4 - 减少,重用,回收
- 转: 编写高效lua代码的方法
- [总结]非托管C++代码调用C#编写的dll方法
- 阅读《Effective Objective-C 2.0 编写高质量iOS与OS X代码的52个有效方法》总结
- 编写高质量OC代码52建议总结:16.提供“全能初始化方法”
- 高效的jQuery代码编写技巧总结
- 高效的jQuery与js代码编写技巧总结
- 编写高效PHP代码总结
- 高效的jQuery代码编写技巧总结
- 高效的jQuery代码编写技巧总结
- 高效的jQuery代码编写技巧总结
- 高效的jQuery代码编写技巧总结
- 编写高质量iOS代码的方法总结
- 大话处理器之编写高效的代码总结