lua的性能優化

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")

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 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")

image

提高的時間是 (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")

image

節省了約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")

image

差別很是大,不管是內存仍是時間,主要緣由是: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")
image

時間相差一倍,也就是說若是不給{}給定初時化大小,當賦值的時候,它會申請空間來存放相應的值。

 

 

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時,改變數據的存儲結構可能減小很大的內存使用。

相關文章
相關標籤/搜索