lua的性能优化
Roberto Ierusalimschy寫過經典的Lua 性能提示的文章,鏈接地址>>
我通過實際的代碼來驗證,發(fā)現一個問題。當我使用 LuaStudio 運行時,發(fā)現結果反而與提示相反,甚是奇怪,而使用luac進行運行,與作者給予的提示相符,在某些地方性能可能有優(yōu)化,比如讀取35kb的文件時,時間還是比較快的(可能5.1版本做過優(yōu)化了)。
?
日常的Lua編碼中,需要注意以下幾點:
1)多使用local
print(_VERSION)local startTime, endTimestartTime = os.clock()for i = 1, 100 * 10000 dolocal x = math.sin(i) endendTime = os.clock()print("[local] used time " .. (endTime - startTime) * 1000 .. " ms")startTime = os.clock()local sin = math.sin for i = 1, 100 * 10000 dolocal x = sin(i) endendTime = os.clock()print("[local] used time " .. (endTime - startTime) * 1000 .. " ms")上面二段代碼,唯一的區(qū)別就是使用 local sin 將 math.sin緩存起來。性能提升約 (107 - 74) / 107 ~= 30.8%,基本符合作者所說的30%的效率提升。
?
startTime = os.clock() function foo(x)for i = 1, 100 * 10000 dox = x + math.sin(i)endreturn x endfoo(10)endTime = os.clock()print("[foo] used time " .. (endTime - startTime) * 1000 .. " ms")startTime = os.clock() function foo2(x)local sin = math.sinfor i = 1, 100 * 10000 dox = x + sin(i)endreturn x endfoo2(10)endTime = os.clock()print("[foo2] used time " .. (endTime - startTime) * 1000 .. " ms")提升的時間是 (125 – 88) /125 = 29.6%,也約為30%(需要多次測試取平均值)
?
使用閉包,避免動態(tài)編譯。
startTime = os.clock() local lim = 10 * 10000 local a = {} for i = 1, lim doa[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 end endlocal lim = 10 * 10000 local a = {} for i = 1, lim doa[i] = fk(i) end endTime = os.clock()print("used time " .. (endTime - startTime) * 1000 .. " ms")節(jié)省了約92%的時間,差異距大。
?
2) 字符串拼接,盡可能使用 table 替代
startTime = os.clock()local buff = "" for line in io.lines("C:/Users/zhangyi/Desktop/xxx.txt") dobuff = 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") dotable.insert(tbl, line) endbuff = table.concat(table, "\n")endTime = os.clock()print(collectgarbage("count") * 1024)print("used time " .. (endTime - startTime) * 1000 .. " ms")差異非常大,無論是內存還是時間,主要原因是:Lua中字符串的拼接都是新創(chuàng)建一個新的字符串,有一個新創(chuàng)建一塊內存、copy字符串的動作,時間、空間上消耗都比較大。
?
3) table使用的優(yōu)化
startTime = os.clock() for i = 1, 100 * 10000 dolocal a = {}a[1] = 1a[2] = 2a[3] = 3 end endTime = os.clock()print("used time " .. (endTime - startTime) * 1000 .. " ms")startTime = os.clock() for i = 1, 100 * 10000 dolocal a = {true, true, true}a[1] = 1a[2] = 2a[3] = 3 end endTime = os.clock()print("used time " .. (endTime - startTime) * 1000 .. " ms")時間相差一倍,也就是說如果不給{}給定初時化大小,當賦值的時候,它會申請空間來存放相應的值。
?
?
local polyline= {}for i = 0, 100 * 10000 dotable.insert(polyline, {x = i, y = 1}) endprint(collectgarbage("count") / 1024)107.57151889801MB
?
local polyline= {}for i = 0, 100 * 10000 dotable.insert(polyline, {i, 1}) endprint(collectgarbage("count") / 1024)77.053853034973MB
?
local polyline= {x = {},y = {} }for i = 0, 100 * 10000 dotable.insert(polyline.x, i)table.insert(polyline.y, i) endprint(collectgarbage("count") / 1024)32.019150733948MB
空間占用差距也非常大,從上面似乎可以得到這樣的結論:盡可能減少table的長度,盡可能使用array 而不是 hash。
?
綜上所述,盡可能多使用local,減少查詢的性能損耗。json數據表如果需要轉化為table時,改變數據的存儲結構可能減少很大的內存使用。
總結
- 上一篇: FortiGuard 实验室报告:全球受
- 下一篇: MIT科学家正在教AI感受电影中的喜怒哀