Le 12 novembre, LuaJIT 2.0.0 a été publié par Mike Pall, après 3 ans de développement et 11 versions bêta. LuaJIT est un interpréteur et compilateur Just In Time pour le langage Lua. L'interpréteur est une machine à registre (et non à pile, comme la JVM ou .NET) avec 93 opcodes.
LuaJIT est compatible, aussi bien au niveau API que ABI, avec Lua 5.1, ce qui signifie que, non seulement tout code source Lua 5.1 fonctionne sur LuaJIT, mais également tout module d'extension natif compilé pour Lua 5.1.
C'est une réécriture complète par rapport à la version 1.x, qui était jusqu'à ce jour la version stable destinée à la production, mais qui ne prenait en charge que l'architecture x86 et n'offrait pas de module FFI (Foreign Function Interface).
LuaJIT est disponible pour les plateformes classiques (Linux, BSD, Mac OS X, Windows), mais aussi pour des plateformes mobiles ou de jeux : Android, iOS, PS3. LuaJIT permet la compilation croisée, il est donc également disponible sur des environnements visant l'embarqué, comme Buildroot.
LuaJIT prend en charge les architectures suivantes : x86, x64, ARM, PPC, MIPS. Toutefois, le mode JIT ne fonctionne pas sur certaines plateformes, comme par exemple iOS ou Windows 8/ARM.
Bref historique des beta
- bêta1 : Première publication, le 31 octobre 2009.
- bêta3 : Ajout de l'architecture x64.
- bêta6 :
- Ajout du port PowerPC/e500v2.
- Introduction du module FFI (_Foreign Function Interface_).
- bêta7 :
- Ajout de l'architecture ARMv5.
- Ajout du mode dual-number.
- bêta8 : Ajout d'un format pour sauvegarder et charger le bytecode généré. Note: ce format est différent de celui de l'interpréteur Lua standard.
- bêta9 : Le module FFI gère les callbacks.
- bêta10 : Ajout de l'architecture MIPS.
- bêta11 :
- Introduction du
goto
provenant de Lua 5.2. - Prise en charge de l'architecture ARMv7 et VFPv3 (FPU).
- Ajout du port PS3.
- Introduction d'un minilua (basé sur Lua 5.1.5) qui permet de générer, au moment de la construction, tous les fichiers sources dépendant des différentes architectures.
- Introduction du
Un exemple de code
Calcul de factorielle :
local function factorial (n)
local a = 1
for i = 1, n do
a = a * i
end
return a
end
for a = 1, 1000 do
print(factorial(7))
end
Le mode interpréteur avec son bytecode :
$ luajit -b -l fact.lua
-- BYTECODE -- fact.lua:1-7
0001 KSHORT 1 1
0002 KSHORT 2 1
0003 MOV 3 0
0004 KSHORT 4 1
0005 FORI 2 => 0008
0006 => MULVV 1 1 5
0007 FORL 2 => 0006
0008 => RET1 1 2
...
La boucle de 1000 permet de mettre en route le mode JIT (ici pour du x86) :
$ luajit -jdump fact.lua
...
---- TRACE 1 mcode 115
...
->LOOP:
b77cefe0 xorps xmm6, xmm6
b77cefe3 cvtsi2sd xmm6, edi
b77cefe7 mulsd xmm7, xmm6
b77cefeb add edi, +0x01
b77cefee cmp edi, eax
b77ceff0 jle 0xb77cefe0 ->LOOP
b77ceff2 jmp 0xb77c7014 ->3
---- TRACE 1 stop -> loop
...
Le mode dual-number
Lua n'a qu'un type number
, l'interpréteur standard utilise les double
du C pour gérer des nombres entiers ou flottants. Le mode dual-number permet de sous-typer dynamiquement, entre entier et flottant. C'est particulièrement utile pour certains processeurs ARM qui n'ont pas de FPU et dont le traitement des flottants est réalisé par des routines logicielles.
Le Module FFI (Foreign Function Interface)
Ce module permet d'accéder à des bibliothèques partagées natives. Et cela, très simplement, en utilisant les déclarations que l'on trouve dans les fichiers d'inclusion du C.
Par exemple :
local ffi = require 'ffi'
ffi.cdef = [[
int printf(const char *fmt, ...);
]]
ffi.C.printf("Hello %s!", "world")
LuaJIT intègre un parseur C (mais sans le pré-processeur pour les #define
, #ifdef
).
Ce module permet aussi de manipuler des structures de données natives avec le langage Lua.
Compatibilité avec Lua 5.2
Pendant les 3 ans de développements de LuaJIT2, la version 5.2 du langage Lua a été publiée. En plus d'être totalement compatible avec Lua 5.1, LuaJIT a intégré certaines nouveautés de Lua 5.2. LuaJIT intègre les nouveautés lexicographiques et syntaxiques (l'ajout du goto
), ainsi qu'une très grande partie des modifications des bibliothèques standards de Lua. En revanche, le nouveau modèle d'environnement des fonctions (_ENV
) est incompatible. De même, l'API C reste celle de Lua 5.1.
Les performances
Le site de LuaJIT présente des comparatifs de performance entre différentes versions de Lua et LuaJIT, pour différentes architectures.
Il y a quelques années, LuaJIT était dans la liste de The Computer Language Benchmarks Game, et les résultats étaient très impressionnants, maintenant il ne reste malheureusement que Lua.
Le modèle de développement
LuaJIT est le fruit du travail d'un seul homme, Mike Pall, qui est un développeur indépendant allemand. Il parvient à se faire rémunérer par certaines sociétés commerciales qui sponsorisent le développement de diverses fonctionnalités.
LuaJIT est diffusé sous la licence MIT, comme Lua.
Les sources sont disponibles dans un dépôt Git (ce qui n'est pas le cas de Lua, où seuls les tarballs sont diffusés).
Depuis mai 2012, LuaJIT a sa propre liste de diffusion, plutôt que d'utiliser celle de Lua.
La suite avec LuaJIT 3.0
Mike Pall nous promet :
- Un nouveau ramasse-miette (incrémental, générationnel et sans copie) qui devrait être évidemment très performant ;
- La prise en charge du préprocesseur C et une prise en charge partielle du C++ pour le module FFI.
Aller plus loin
- Site officiel de LuaJIT (207 clics)
- Site officiel de Lua (71 clics)
- Présentation de LuaJIT à l'OSDC.fr 2011 (PDF) (56 clics)
- Présentation de Lua et son écosystème à l'OSDC.fr 2011 (PDF) (300 clics)
# Pour se faire une idée des perfs
Posté par jseb . Évalué à 10.
Le gros avantage de LuaJIT est qu'il ne nécessite aucun travail préparatoire pour remplacer l'interpréteur Lua.
C'est aussi simple que de remplacer ceci:
$~ lua foo.lua
par cela:
$~ luajit foo.lua
Et les résultats sont vraiment impressionants. Déja que Lua est plutôt rapide pour un langage interprété, LuaJIT passe vraiment la vitesse supérieure.
Il est vrai qu'il est dommage que LuaJIT ait été enlevé du «shootout benchmark».
Néanmoins, pour se faire une idée de ses performances par rapport à Lua, on peut consulter la page dédiée sur le site de Mike Pall. Par exemple, pour les x86 et x86_64:
http://luajit.org/performance_x86.html
Discussions en français sur la création de jeux videos : IRC libera / #gamedev-fr
[^] # Re: Pour se faire une idée des perfs
Posté par Firwen (site web personnel) . Évalué à 7.
Tiens une news sur luaJIT, surprise du jour
J'ai toujours trouvé le gain de performance de LuaJIT simplement hallucinant..
Sur les tests du shootout, LuaJIT avait des perfs qui rivalisait avec "java -server", c'est à ma connaissance le seul langage à typage dynamique/prototype qui peut se permettre ce genre de fantaisie, tous les autres sont loin, trés loin derrière ( d'un facteur 20 environ.. )
[^] # Re: Pour se faire une idée des perfs
Posté par patrick_g (site web personnel) . Évalué à 3.
y compris PyPy ?
[^] # Re: Pour se faire une idée des perfs
Posté par Firwen (site web personnel) . Évalué à 2.
Y compris pypy, je n'ai plus les nombres exactes en tête mais luaJIT mettait un facteur 10 à pypy environ…
ça doit être possible de se refaire un benchmark maison en fouillant un peu sur le shootaut ;)
[^] # Re: Pour se faire une idée des perfs
Posté par catwell (site web personnel) . Évalué à 3.
Non seulement PyPy, mais aussi toutes les VM JavaScript. En fait sur du calcul scientifique (genre SciMark) LuaJIT est souvent plus rapide que le code C équivalent.
En plus de ça, la FFI de LuaJIT est vraiment incroyable. La capacité à simplement utiliser n'importe quelle bibliothèque dynamique palie la faible taille de l'écosystème Lua et l'utilisation de ctypes règle souvent les problèmes de mémoire propre aux langages dynamiques.
Au passage les performances ne viennent pas seulement du JIT. Même en le désactivant, ou sur les plate-formes où il n'est pas disponible, l'interpréteur est plus rapide que l'implémentation de référence PUC Lua d'un facteur 4 environ. Bien sûr ça se paye par une complexité supplémentaire et une portabilité limitée (lire le code de LuaJIT est un bon exercice au passage :p).
Personnellement ça fait quelques années que Lua est mon langage de prédilection, d'abord pour du scripting dans une application C, mais de plus en plus de manière standalone grâce à LuaJIT.
[^] # Re: Pour se faire une idée des perfs
Posté par wilk . Évalué à 2.
Facteur 10, facteur 20… Il faudrait peut-être quelques exemples sinon on se retrouve un peu à laver plus blanc que blanc !
[^] # Re: Pour se faire une idée des perfs
Posté par HardShooter . Évalué à 2.
Voila un article qui peut expliquer la différence de perfs entre PyPy et Luajit : http://alexgaynor.net/2011/apr/03/my-experience-computer-language-shootout/
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.