Reputation: 777
Say I have a cdata
variable (a result of a FFI query). Then I copy its fields to a Lua table. What is faster: access fields of the Lua table or of the original cdata
variable?
Upvotes: 2
Views: 554
Reputation: 86
With disabled JIT, table key lookup is the way much faster due to LuaJIT table internal structure and collision handling optimizations (e.g. Brent's variation). For cdata
TGETS/TGETV implies a metamethod lookup and its further execution. Here is the method implementing field (i.e. key) lookup.
With enabled JIT both table slot and structure field addresses/offsets are specialized on the trace with several assertion guards prior it. Omitting such assertion failures (e.g. caused by table reallocation, that leads to the slot address invalidation), the performance difference can be considered neglible.
I see nice benchmarks by @mons-anderson also confirming it.
Upvotes: 3
Reputation: 421
Let's just check it
With jit:
./tarantool -l clock -l ffi
Tarantool 2.3.1-18-ga5a2bb28a
type 'help' for interactive help
tarantool> ffi.cdef[[ typedef struct test { int field; } ]]
---
...
tarantool> T = ffi.typeof('struct test')
---
...
tarantool> F = T({12345})
---
...
tarantool> L = {field = 12345}
---
...
tarantool> local st = clock.proc() for i=1,1e8 do local x = F.field end return clock.proc() - st
---
- 0.036895
...
tarantool> local st = clock.proc() for i=1,1e8 do local x = L.field end return clock.proc() - st
---
- 0.037841
...
And without jit:
tarantool> jit.off()
---
...
tarantool> local st = clock.proc() for i=1,1e6 do local x = F.field end return clock.proc() - st
---
- 0.198209
...
tarantool> local st = clock.proc() for i=1,1e6 do local x = L.field end return clock.proc() - st
---
- 0.010116
...
So, the summary:
Upvotes: 3