標籤:lua
LuaJIT本身對Lua作了很多方面的最佳化工作,對很多Lua內建的庫函數進行了最佳化。
最佳化詳情:http://wiki.luajit.org/NYI
wiki:http://wiki.luajit.org/Home
關於Lua最佳化的一些細節:
1.經常使用的庫函數,使用local方式來調用,注意僅一次調用是不起作用的。
--this is the lowest method string.rep()--this is a better way local rep = string.rep
2.建立table時,事先分配好大小。
--allocate the table when you declare it local tbl = {nil,nil} table.insert(tbl,1) table.insert(tbl,2)
lua table的記憶體配置按照2的N次方遞增,所以在不斷table.insert的過程中,會在前期頻繁的申請記憶體空間因此事先申請好記憶體能夠提升效能。
3.避免一些長字串的format操作,長字串的format操作效率低下,對於長字串可以考慮使用..操作來進行字串串連,效率比format高。
local str = [==[ hello %s ]==]string.format(str,"world")local str = [[hello]]return str.. "world"
4.一個檔案中的函數盡量使用local方式來定義
local plus = function(a,b) return a+b end
5.一些結構的最佳化。這裡我們定義了一個Filter,其中有typeA和typeB 2種類型的filter,遍曆這些filter,我們有3種方式封裝API:
--now we define a filter--we get three ways to define it---all filters listedlocal Filter = {nil,nil}local Filter.typeA = {nil,nil}local Filter.typeB = {nil,nil}Filter.typeA.filter1 = function()endFilter.typeA.filter2 = function()endFilter.typeB.filter1 = function()end Filter.typeB.filter2 = function()end--first wayfunction handler(arg) if not Filter.typeA.filter1() then return false end if not Filter.typeA.filter2() then return false end if not Filter.typeB.filter1() then return false end if not Filter.typeB.filter2() then return false end return trueend --second wayfunction handler(arg) for k,func in pairs(Filter.typeA) do if not func() then return false end for k,func in pairs(Filter.typeB) do if not func() then return false end end return trueend--third waylocal func_name_list = { ‘filter1‘,‘filter2‘}function handler(arg) for _,name in ipairs(func_name_list) do if not Filter.typeA[name]() then return false end if not Filter.typeB[name]() then return false end end return trueend--fourth waylocal typeA_func_list = { Filter.typeA.filter1(), Filter.typeA.filter2() } local typeB_func_list = { Filter.typeB.filter1(), Filter.typeB.filter2() }function handler(arg) for _,func in ipairs(typeA_func_list) do if not func() then return false end end for _,func in ipairs(typeB_func_list) do if not func() then return false end end return trueend
這裡值得注意的是,LuaJIT針對ipairs作了相當的最佳化,但是對於pairs,LuaJIT中沒有作最佳化,在一些table中我們盡量避免使用hash表,遍曆的時候使用iparis。
第一種方式是效率最高的,但是結構很糟糕,代碼維護起來比較難。
第二種方式遍曆效率極低。
第三種效率不錯,代碼結構一般。
第四種是最好的遍曆方式,結構也很不錯。我們採用這種方式是最優的。
6.關於table的遍曆
在LuaJIT中針對ipairs作了相當的最佳化,但是對pairs沒有最佳化。另外對於一些遍曆,盡量使用for i,#table do end 來進行遍曆。LuaJIT中針對for遍曆也進行了最佳化。對於數組盡量使用for來遍曆,這是最快的遍曆方式。
7.關於config的載入,首先看測試指令碼
-- conf_table.lua local conf_table = {nil,nil,nil} conf_table.A = "string A" conf_table.B = "string B" conf_table.C = "string C" return conf_table
-- conf_notbl.lua
A = "string A"
B = "string B"
C = "string C"
-- conf_test.lua
require ‘conf_notbl‘
local conf = require ‘conf_table‘
local socket = require ‘socket‘
local round = 10000000
local time = socket.gettime()
for i=1,round do
local x = A
local y = B
local z = C
end
print("conf before :" .. (socket.gettime()-time)*1000 .. "ms")
local time = socket.gettime()
for i=1,round do
local x = conf.A
local y = conf.B
local z = conf.C
end
print("conf table :" .. (socket.gettime()-time)*1000 .. "ms")
local a1=A
local a2=B
local a3=C
local time = socket.gettime()
for i=1,round do
local x = a1
local y = a2
local z = a3
end
print("local conf :" .. (socket.gettime()-time)*1000 .. "ms")
測試結果:
Lua:
conf before :742.80691146851ms
conf table :789.02816772461ms
local conf :403.17010879517ms
LuaJIT:
conf before :4.1639804840088ms
conf table :4.1368007659912ms
local conf :3.9420127868652ms
在使用lua檔案來載入config的時候,盡量使用local方式來將經常使用的conf的資料存起來,如果使用次數不多,這樣做就沒有必要了。
另外特意使用一個table來儲存conf資料並沒有必要,但是這樣做config結構比較好。