Roberto Ierusalimschy寫過經典的Lua 性能提示的文章,連接地址>>json
我經過實際的代碼來驗證,發現一個問題。當我使用 LuaStudio 運行時,發現結果反而與提示相反,甚是奇怪,而使用luac進行運行,與做者給予的提示相符,在某些地方性能可能有優化,好比讀取35kb的文件時,時間仍是比較快的(可能5.1版本作過優化了)。緩存
平常的Lua編碼中,須要注意如下幾點:閉包
1)多使用local性能
print(_VERSION) local startTime, endTime startTime = os.clock() for i = 1, 100 * 10000 do local x = math.sin(i) end endTime = os.clock() print("[local] used time " .. (endTime - startTime) * 1000 .. " ms") startTime = os.clock() local sin = math.sin for i = 1, 100 * 10000 do local x = sin(i) end endTime = os.clock() print("[local] used time " .. (endTime - startTime) * 1000 .. " ms")
上面二段代碼,惟一的區別就是使用 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 x end foo(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 x end foo2(10) endTime = os.clock() print("[foo2] used time " .. (endTime - startTime) * 1000 .. " ms")
提高的時間是 (125 – 88) /125 = 29.6%,也約爲30%(須要屢次測試取平均值)優化
使用閉包,避免動態編譯。編碼
startTime = os.clock() local lim = 10 * 10000 local a = {} for i = 1, lim do a[i] = loadstring(string.format("return %d", i)) end print(a[10]()) endTime = os.clock() print("used time " .. (endTime - startTime) * 1000 .. " ms") startTime = os.clock() function fk(k) return function() return k end end local lim = 10 * 10000 local a = {} for i = 1, lim do a[i] = fk(i) end endTime = os.clock() print("used time " .. (endTime - startTime) * 1000 .. " ms")
節省了約92%的時間,差別距大。lua
2) 字符串拼接,儘量使用 table 替代spa
startTime = os.clock() local buff = "" for line in io.lines("C:/Users/zhangyi/Desktop/xxx.txt") do buff = buff .. line .. "\n" end endTime = 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) end buff = table.concat(table, "\n") endTime = os.clock() print(collectgarbage("count") * 1024) print("used time " .. (endTime - startTime) * 1000 .. " ms")
差別很是大,不管是內存仍是時間,主要緣由是:Lua中字符串的拼接都是新建立一個新的字符串,有一個新建立一塊內存、copy字符串的動做,時間、空間上消耗都比較大。code
3) table使用的優化
startTime = os.clock() for i = 1, 100 * 10000 do local a = {} a[1] = 1 a[2] = 2 a[3] = 3 end endTime = 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] = 3 end endTime = os.clock() print("used time " .. (endTime - startTime) * 1000 .. " ms")
時間相差一倍,也就是說若是不給{}給定初時化大小,當賦值的時候,它會申請空間來存放相應的值。
local polyline= {} for i = 0, 100 * 10000 do table.insert(polyline, {x = i, y = 1}) end print(collectgarbage("count") / 1024)
107.57151889801MB
local polyline= {} for i = 0, 100 * 10000 do table.insert(polyline, {i, 1}) end print(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) end print(collectgarbage("count") / 1024)
32.019150733948MB
空間佔用差距也很是大,從上面彷佛能夠獲得這樣的結論:儘量減小table的長度,儘量使用array 而不是 hash。
綜上所述,儘量多使用local,減小查詢的性能損耗。json數據表若是須要轉化爲table時,改變數據的存儲結構可能減小很大的內存使用。