博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
lua的性能优化
阅读量:4559 次
发布时间:2019-06-08

本文共 3380 字,大约阅读时间需要 11 分钟。

Roberto Ierusalimschy写过经典的Lua 性能提示的文章,

我通过实际的代码来验证,发现一个问题。当我使用 LuaStudio 运行时,发现结果反而与提示相反,甚是奇怪,而使用luac进行运行,与作者给予的提示相符,在某些地方性能可能有优化,比如读取35kb的文件时,时间还是比较快的(可能5.1版本做过优化了)。

 

日常的Lua编码中,需要注意以下几点:

1)多使用local

print(_VERSION)local startTime, endTimestartTime = os.clock()for i = 1, 100 * 10000 do    local x = math.sin(i)endendTime = os.clock()print("[local] used time " .. (endTime - startTime) * 1000 .. " ms")startTime = os.clock()local sin = math.sinfor i = 1, 100 * 10000 do    local x = sin(i)endendTime = os.clock()print("[local] used time " .. (endTime - startTime) * 1000 .. " ms")

image

上面二段代码,唯一的区别就是使用 local sin 将 math.sin缓存起来。性能提升约 (107 - 74) / 107 ~= 30.8%,基本符合作者所说的30%的效率提升。

 

startTime = os.clock()function foo(x)    for i = 1, 100 * 10000 do        x = x + math.sin(i)    end    return xendfoo(10)endTime = os.clock()print("[foo] used time " .. (endTime - startTime) * 1000 .. " ms")startTime = os.clock()function foo2(x)    local sin = math.sin    for i = 1, 100 * 10000 do        x = x + sin(i)    end    return xendfoo2(10)endTime = os.clock()print("[foo2] used time " .. (endTime - startTime) * 1000 .. " ms")

image

提升的时间是 (125 – 88) /125 = 29.6%,也约为30%(需要多次测试取平均值)

 

使用闭包,避免动态编译。

startTime = os.clock()local lim = 10 * 10000local a = {}for i = 1, lim do    a[i] = loadstring(string.format("return %d", i))endprint(a[10]())endTime = os.clock()print("used time " .. (endTime - startTime) * 1000 .. " ms")startTime = os.clock()function fk(k)    return function() return k endendlocal lim = 10 * 10000local a = {}for i = 1, lim do    a[i] = fk(i)endendTime = os.clock()print("used time " .. (endTime - startTime) * 1000 .. " ms")

image

节省了约92%的时间,差异距大。

 

2) 字符串拼接,尽可能使用 table 替代

startTime = os.clock()local buff = ""for line in io.lines("C:/Users/zhangyi/Desktop/xxx.txt") do    buff = buff .. line .. "\n"    endendTime = os.clock()print(collectgarbage("count") * 1024)print("used time " .. (endTime - startTime) * 1000 .. " ms")startTime = os.clock()local buff = ""local tbl = {}for line in io.lines("C:/Users/zhangyi/Desktop/xxx.txt") do    table.insert(tbl, line)endbuff = table.concat(table, "\n")endTime = os.clock()print(collectgarbage("count") * 1024)print("used time " .. (endTime - startTime) * 1000 .. " ms")

image

差异非常大,无论是内存还是时间,主要原因是:Lua中字符串的拼接都是新创建一个新的字符串,有一个新创建一块内存、copy字符串的动作,时间、空间上消耗都比较大。

 

3) table使用的优化

startTime = os.clock()for i = 1, 100 * 10000 do    local a = {}    a[1] = 1    a[2] = 2    a[3] = 3endendTime = os.clock()print("used time " .. (endTime - startTime) * 1000 .. " ms")startTime = os.clock()for i = 1, 100 * 10000 do    local a = {
true, true, true} a[1] = 1 a[2] = 2 a[3] = 3endendTime = os.clock()print("used time " .. (endTime - startTime) * 1000 .. " ms")
image

时间相差一倍,也就是说如果不给{}给定初时化大小,当赋值的时候,它会申请空间来存放相应的值。

 

 

local polyline= {}for i = 0, 100 * 10000 do    table.insert(polyline, {x = i, y = 1})endprint(collectgarbage("count") / 1024)

107.57151889801MB

 

local polyline= {}for i = 0, 100 * 10000 do    table.insert(polyline, {i, 1})endprint(collectgarbage("count") / 1024)

77.053853034973MB

 

local polyline= {    x = {},    y = {}}for i = 0, 100 * 10000 do    table.insert(polyline.x, i)    table.insert(polyline.y, i)endprint(collectgarbage("count") / 1024)

32.019150733948MB

空间占用差距也非常大,从上面似乎可以得到这样的结论:尽可能减少table的长度,尽可能使用array 而不是 hash。

 

综上所述,尽可能多使用local,减少查询的性能损耗。json数据表如果需要转化为table时,改变数据的存储结构可能减少很大的内存使用。

转载于:https://www.cnblogs.com/meteoric_cry/p/8000948.html

你可能感兴趣的文章
win10下VS2010中文输入法切换为英文卡死
查看>>
retinex相关代码汇总
查看>>
Cortex-M3 异常返回值EXC_RETURN
查看>>
kettle 转换字段遇到问题(couldn't get row from result set)——摘
查看>>
nginx首页根据IP跳转
查看>>
【2019-08-20】有点目标,有点计划,有点目的
查看>>
【2019-09-10】美,真的跟年龄无关
查看>>
【2019-09-28】少,但更好
查看>>
【2019-09-13】耐心观察是一种技能
查看>>
mysql数据库2-常用命令
查看>>
安卓开发环境搭建(转)
查看>>
英语学习一周年
查看>>
set容器
查看>>
python基础学习目录
查看>>
卷积神经网络是如何工作的(译文)
查看>>
微信开发 笔记1
查看>>
SQL server 删除日志文件 秒删
查看>>
MethodChannel 实现flutter 与 原生通信
查看>>
lua的性能优化
查看>>
vs2012 出现断点无法命中 解决方案。
查看>>