常见的Lua优化小技巧
Lua常见优化点:
1. 尽量使用局部变量
function sumGlobal(n)
local sum = 0
for i = 1, n do
sum = sum + GLOBAL_VALUE
end
return sum
end
function sumLocal(n)
local sum = 0
local local_value = GLOBAL_VALUE
for i = 1, n do
sum = sum + local_value
end
return sum
end
GLOBAL_VALUE = 1
local n = 1000000
local start_time = os.clock()
sumGlobal(n)
print("sumGlobal:", os.clock() - start_time)
start_time = os.clock()
sumLocal(n)
print("sumLocal:", os.clock() - start_time)
2. table的相关
减少对表的访问
local t = {x = 1, y = 2, z = 3}
function accessTableDirectly(n)
local sum = 0
for i = 1, n do
sum = sum + t.x + t.y + t.z
end
return sum
end
function accessTableLocally(n)
local sum = 0
local x, y, z = t.x, t.y, t.z
for i = 1, n do
sum = sum + x + y + z
end
return sum
end
n = 1000000
start_time = os.clock()
accessTableDirectly(n)
print("accessTableDirectly:", os.clock() - start_time)
start_time = os.clock()
accessTableLocally(n)
print("accessTableLocally:", os.clock() - start_time)
for循环
local t = {}
for i = 1, 1000000 do
t[i] = i
end
function genericForLoop(n)
local sum = 0
for _, v in ipairs(t) do
sum = sum + v
end
return sum
end
function numericForLoop(n)
local sum = 0
for i = 1, n do
sum = sum + t[i]
end
return sum
end
n = 1000000
start_time = os.clock()
genericForLoop(n)
print("genericForLoop:", os.clock() - start_time)
start_time = os.clock()
numericForLoop(n)
print("numericForLoop:", os.clock() - start_time)
预分配表空间
function dynamicTable(n)
local t = {}
for i = 1, n do
t[i] = i
end
return t
end
function preallocatedTable(n)
local t = {}
for i = 1, n do
t[i] = i
end
return t
end
n = 1000000
start_time = os.clock()
dynamicTable(n)
print("dynamicTable:", os.clock() - start_time)
start_time = os.clock()
preallocatedTable(n)
print("preallocatedTable:", os.clock() - start_time)
元表
local start_time = os.clock()
local function createObject()
local obj = {}
setmetatable(obj, {
__index = function(t, k)
return "value"
end,
__newindex = function(t, k, v)
rawset(t, k, v)
end,
})
return obj
end
for i = 1, 1000000 do
local obj = createObject()
local value = obj.some_key
end
print("Time taken with frequent setmetatable:", os.clock() - start_time)
local start_time = os.clock()
local mt = {
__index = function(t, k)
return "value"
end,
__newindex = function(t, k, v)
rawset(t, k, v)
end,
}
local function createObject()
local obj = {}
setmetatable(obj, mt)
return obj
end
for i = 1, 1000000 do
local obj = createObject()
local value = obj.some_key
end
print("Time taken with predefined metatable:", os.clock() - start_time)
local start_time = os.clock()
local mt = {
__index = function(t, k)
return "value"
end,
__newindex = function(t, k, v)
rawset(t, k, v)
end,
}
local obj = setmetatable({}, mt)
local __index = mt.__index
for i = 1, 1000000 do
local value = __index(obj, "some_key")
end
print("Time taken with cached metatable method:", os.clock() - start_time)
3. string的相关
function concatOperator(n)
local str = ""
for i = 1, n do
str = str .. i
end
return str
end
function concatTable(n)
local t = {}
for i = 1, n do
t[#t + 1] = i
end
return table.concat(t)
end
n = 10000
start_time = os.clock()
concatOperator(n)
print("concatOperator:", os.clock() - start_time)
start_time = os.clock()
concatTable(n)
print("concatTable:", os.clock() - start_time)
4. 避免运行时加载编译
local start_time = os.clock()
for i = 1, 1000000 do
local code = "return " .. i
local func = load(code)
func()
end
print("Runtime compilation:", os.clock() - start_time)
local start_time = os.clock()
for i = 1, 1000000 do
local func = function() return i end
func()
end
print("Avoid runtime compilation:", os.clock() - start_time)
5. 尽量避免频繁创建临时对象
闭包
local start_time = os.clock()
local function createClosures1()
local closures = {}
for i = 1, 1000000 do
closures[i] = function() return i end
end
return closures
end
local closures = createClosures1()
print("Frequency of closure creation:", os.clock() - start_time)
for i = 1, 10 do
print(closures[i]())
end
local start_time = os.clock()
local function createClosures2()
local closures = {}
local function createClosure2(i)
return function() return i end
end
for i = 1, 1000000 do
closures[i] = createClosure2(i)
end
return closures
end
local closures = createClosures2()
print("Avoid frequency of closure creation:", os.clock() - start_time)
for i = 1, 10 do
print(closures[i]())
end
表
local start_time = os.clock()
local function createTables1()
local tables = {}
for i = 1, 1000000 do
tables[i] = {x = i, y = i * 2}
end
return tables
end
local tables = createTables1()
print("Frequency of table creation:", os.clock() - start_time)
local start_time = os.clock()
local function createTables2()
local tables = {}
local tempTable = {x = 0, y = 0}
for i = 1, 1000000 do
tempTable.x = i
tempTable.y = i * 2
tables[i] = {x = tempTable.x, y = tempTable.y}
end
return tables
end
local tables = createTables2()
print("Avoid frequency of table creation:", os.clock() - start_time)
local start_time = os.clock()
local function createTables()
local tables = {}
for i = 1, 1000000 do
tables[i] = tables[i] or {x = 0, y = 0}
tables[i].x = i
tables[i].y = i * 2
end
return tables
end
local tables = createTables()
print("Further optimized table creation:", os.clock() - start_time)