Lua templating/Optimisation

Optimisation is generally only necessary when lua modules are misused or inefficient.
== Important note ==
"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil." The fallacy of premature optimization.
. http://ubiquity.acm.org/article.cfm?id=1513451
==General guidelines==
If for whatever reason your modules are exceeding the limit, you should then consider optimising.
Whenever possiblehttp://www.lua.org/gems/sample.pdf :
* Use local functions or variables
* Avoid nested functions
* Use arrays instead of tables (hashing)
* Use local variables instead of indexing tables
Simple optimisations such as copying a global function (e.g. string.match) may greatly improve performance of a module.
Tip: Use os.clock() before and after a code "chunk" and subtract the two results to evaluate the code section's  performance.
=== String vs table concatenation ===
When dealing with potentially huge strings, it is more efficient to add them to a table and use table.concat rather than simply using "join" or concatenating them http://www.lua.org/pil/11.6.html.<tabber>
|-|Manual concatenation=
-- This is slower
local people = {"John", "Mary", "Parker", "Sue", "Anonymous", "..."}
local text = ""
for i = 1, #people do
 if i > 1 then
 text = ", " .. text
 end
 text = text .. people[i]
end
print(text)
|-|table.concat=
-- This is faster
local people = {"John", "Mary", "Parker", "Sue", "Anonymous", "..."}
local text = table.concat(people, ", ")
print(text)
</tabber>
=== Use tables for SQL-IN alike compares ===
This means that instead of having a lot of if statements a better alternative is to put them all in a set-like tablehttp://stackoverflow.com/a/12865406. For example, this is a typical if structure:
local function foo(value)
 if value == "foo" or value == "bar" or value == "baz" or value == "qux"
 or value == "lorem" or value == "ipsum" then
 return "something"
 end
 return "something else"
end
... and this is a more efficient, table-based one:
local function foo(value)
 local validValues = {
 foo = true,
 bar = true,
 baz = true,
 qux = true,
 lorem = true,
 ipsum = true
 }
 if validValues[value] then
 return "something"
 end
 return "something else"
end
Note that you can use any truthy value, instead of just true.
== Templates ==
Using too many template transclusions in a single page is one common problem that affects the speed of lua. Each invocation will count towards the lua limit.
There are multiple techniques to overcome this:
* Consolidate - move all code to a module, and restructure it to only be called fewer times
* Rewrite the code to be more efficient.
=== Change template "databases" into data modules ===
Making templates databases causes a lot of issues such as becoming cumbersome to use, and slower if they use parser functions. One idea is adding them to a module, as described in Lua templating/Converting Wikitext templates.
If the template is used several times on a page, consider using mw.loadData to load its data, instead of require:
 local data = mw.loadData("Module:Mystuff")
 return data[frame.args[1]]
=== Avoid multiple invocations to the same module ===
Instead of this for example:
local p = {}
function p.showpopulation(frame)
 local pop = {china= 50, australia = 20, ghana = 10}
 return pop[frame.args[1]]
end
return p
{{#invoke:mymodule:showpopulation|china}}
{{#invoke:mymodule:showpopulation|australia}}
{{#invoke:mymodule:showpopulation|ghana}}
Do this:
local p = {}
function p.showpopulation(frame)
 local pop = {china= 50, australia = 20, ghana = 10}
 local args = frame.args
 return pop[args[1]] .." ".. (pop[args[2]] or "") .. " " ..(pop[args[3]] or "")
end
return p
{{#invoke:mymodule:showpopulation
|china
|australia
|ghana}}
== References ==
Category:Lua