Lua and Luajit Best Practices?

The following thread is intended to collect all the good ways to use Lua/Luajit within Defold.
Some of the information will include:

  • General Lua performance with respect to language use
  • How to tweak luajit to perform that little bit better
  • FFI specific performance improvements (for those targeting platform external libs)
  • Interop performance notes for native libraries.
  • Defold specific optimizations

Hopefully this could be a useful reference of common links and information that people can add to over time.

Initial References
Defold Optimisation Page

Lua Classic Tips:

Luajit Performance Tips:

Luajit Performance Tips (from Mike Pall):


Luajit projects useful for learning interop:
UFO Excellent examples of luajit ffi

Lua for Windows:
A huge array of interop libraries for windows. You can make almost any application using these.

These projects provide a huge array of samples and libraries for people to learn Lua and Luajit with. Highly recommended to new Lua users.


Some quick tips for lua performance:
Always create local references to methods within tables if they are going to be called many times.
The example here is using tables. Put this at the top of your lua file, and this will improve perf if you are operating on tables many times in a frame.

local tinsert = table.insert
local tremove = table.remove 
local tconcat = table.concat

You can do this with any module or lua script table you are using.


Another classic perf tip:
Always try to use ipairs if you intend to do a large amount of iteration within the main game frame at runtime.

-- Do this
for i,v in ipairs(mytablelist) do ... something .. end 
-- Try not to do this
for k,v in pairs(mytablelist) do ... something .. end 

If you need to use key tables, try to use them for lookups and not for iteration.


Another lua handy tip. This is not performance related, but it is a look into the wonderful world of metatables and metamethods :wink:
Often you want to get a size of a table. You can iterate the table, and if you use insert and remove then table.getn will work most of the time. But it can be frustrating because using a table[key] = value can break getn.
What to do? Metatables!!! This is a little OO like but heres an example of a table with some metamethods that help solve the above problem.

local myobject = {}
local mt = {
  __newindex = function (tbl, key, value) 
       if(key == "count") then return end -- dont allow count modification!
       if(tbl[key] == nil) then tbl.count = (tbl.count or 0) + 1 end
       if(value == nil and tbl[key]) then tbl.count = tbl.count -1 end
       tbl[key] = value 
setmetatable(myobject, mt) 

Now when you use myobject[key]=value the myobject will have a count properties added that shows how many indexes are added and removed using the newindex ([]) method.
When combined with other functions and metamethods you can do some really nice things to make managing tables much easier and more intuitive to the developer.