Lua Local Optimisation
Local optimisation keeps values a loop uses often in local variables. A local copy is made once, before the loop, and then reused on every pass.
Localise a function before the loop
The local name sqrt is a copy of math.sqrt. Calls then use the local name.
local sqrt = math.sqrt
print(sqrt(16), sqrt(9))Count lookups with and without a local
A counting table stands in for a looked-up value. The local version reads it once, and both versions reach the same total.
local lookups = 0
local lib = setmetatable({}, {__index = function(_, k) lookups = lookups + 1 return 16 end})
local function byLookup()
lookups = 0
local total = 0
for i = 1, 4 do total = total + lib.value end
return total, lookups
end
local function byLocal()
lookups = 0
local value = lib.value
local total = 0
for i = 1, 4 do total = total + value end
return total, lookups
end
local t1, l1 = byLookup()
local t2, l2 = byLocal()
print(t1, l1)
print(t2, l2)Copy a looked-up function once
The function is fetched once and stored in a local. Later calls reuse that local, so the lookup count stays at one.
local lookups = 0
local lib = setmetatable({}, {__index = function() lookups = lookups + 1 return function(x) return x + 10 end end})
local add = lib.add
print(lookups)
print(add(5))
print(add(5))
print(lookups)Example
local sqrt = math.sqrt
local step = 2
local total = 0
for i = 1, 4 do total = total + sqrt(i * i) + step end
print(total)Key points
- Local variable: a variable declared with local and visible only in its block.
- Local copy: a local variable that keeps a value once, before a loop.
- Use a local copy for a function a loop calls on every pass.
- Use a local copy for a value a loop reads on every pass.
- A local copy does not change the result, only how often the lookup runs.
In this example, sqrt is copied to a local before the loop, and step is held in a local too. Each pass adds one square root and the step value. The printed total is the sum of those passes.
Note
copy the value before the loop, not inside it, or the lookup runs on every pass.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
Which change cuts repeated lookups inside a loop?