Skip to content
Learni
View all tutorials
Développement

Comment optimiser les performances avec Lua en 2026

Introduction

Lua excelle dans les environnements embarqués et les jeux grâce à sa légèreté. En 2026, les exigences de performance exigent une maîtrise profonde des métatables, coroutines et LuaJIT. Ce tutoriel vous guide pas à pas vers des optimisations concrètes et mesurables.

Prérequis

  • Lua 5.4 ou LuaJIT 2.1+
  • Connaissances solides en tables et fonctions
  • Compilateur C pour extensions
  • Outil de benchmark comme bench.lua

Métatables dynamiques avancés

metatable.lua
local mt = {
  __index = function(t, k)
    if k == "computed" then return t.base * 2 end
    return rawget(t, k)
  end,
  __newindex = function(t, k, v)
    if k == "locked" then error("Champ verrouillé") end
    rawset(t, k, v)
  end
}
local obj = setmetatable({base = 10}, mt)
print(obj.computed) -- 20

Ce métatable implémente un calcul paresseux et une protection contre les modifications. Il évite les boucles infinies grâce à rawget/rawset.

Coroutines pour tâches asynchrones

coroutine.lua
local co = coroutine.create(function()
  for i = 1, 3 do
    print("Étape", i)
    coroutine.yield()
  end
end)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)

Les coroutines permettent un contrôle fin du flux sans threads OS. Chaque yield suspend l'exécution pour reprendre exactement là où elle s'était arrêtée.

Optimisation LuaJIT FFI

ffi_opt.lua
local ffi = require("ffi")
ffi.cdef[[
  typedef struct { double x, y; } Point;
]]
local Point = ffi.typeof("Point")
local p = Point(1.0, 2.0)
print(p.x + p.y)

FFI de LuaJIT permet d'appeler du code C natif sans overhead. Utilisez-le pour les boucles critiques afin d'atteindre des performances proches du C pur.

Module haute performance

perf_module.lua
local M = {}
M.cache = setmetatable({}, {__mode = "v"})
function M.compute(key, fn)
  if M.cache[key] then return M.cache[key] end
  local res = fn()
  M.cache[key] = res
  return res
end
return M

Ce module implémente un cache faible avec mode 'v'. Il évite les fuites mémoire tout en accélérant les calculs répétés.

Benchmark et profiling

benchmark.lua
local start = os.clock()
for i = 1, 1000000 do
  -- code à mesurer
end
print("Temps:", os.clock() - start)

Utilisez os.clock pour des mesures précises. Combinez avec LuaJIT -joff pour comparer les performances JIT vs interprété.

Bonnes pratiques

  • Préférez les tables locales aux globales
  • Évitez les créations de closures dans les boucles chaudes
  • Utilisez collectgarbage("count") pour surveiller la mémoire
  • Précompilez les scripts avec luac -O3
  • Testez systématiquement avec et sans JIT

Erreurs courantes à éviter

  • Oublier rawget/rawset dans les métaméthodes crée des récursions infinies
  • Utiliser des coroutines avec des ressources non yield-safe
  • Ignorer les différences entre Lua et LuaJIT en production
  • Ne pas vider les caches faibles régulièrement

Pour aller plus loin

Approfondissez avec nos formations Lua avancées.