常见的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)