Re: FFI in interpreter mode

  • From: Mike Pall <mike-1205@xxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Tue, 29 May 2012 18:13:21 +0200

Douglas Creager wrote:
> > But please note that the FFI functionality is rather slow in
> > interpreted mode. Should be ok for the occasional C call, though.
> Is the legacy C API faster than the FFI in LuaJIT's interpreted mode?
> We have several wrapper modules that we've written both legacy and FFI
> versions of, and we dynamically select at runtime which to load based on
> the result of
>    pcall(require, "ffi")
> But if legacy is faster than FFI in the LuaJIT interpreter, then we
> could augment that with a call to jit.status() and only enable the FFI
> bindings if the JIT compiler is enabled.

If you actually depend on the speed of calling C functions and you
don't mind the space overhead of the extra classic Lua/C bindings,
then you should probably opt for the classic binding, if the JIT
compiler is disabled/unavailable (e.g. on iOS).

But if the JIT compiler is enabled, calls via the FFI are _much_
faster than anything else.

The speed difference depends on the number and type of arguments
that need to be passed and returned. Calls to C functions bound
via the classic API are about 2x-3x faster with LuaJIT than with
Lua (remember, that's even though the classic API calls are not
JIT-compiled). And FFI calls are about 20x-30x (!) faster, if JIT-
compiled. Sadly, interpreted FFI calls are around 5x slower than
classic API calls with LuaJIT.

So, yes, you should avoid performance-sensitive FFI C calls in the
no-JIT case. But I guess, it would be perfectly ok for GUIs or a
bit of I/O.

Note that no effort has been put in to make the FFI fast for the
no-JIT case. But I doubt it's worth the trouble.


Other related posts: