访问 Lua table 字段是否比访问 cdata 字段更快?
Is accessing a Lua table field faster then accessing a cdata field?
假设我有一个 cdata
变量(FFI 查询的结果)。然后我将它的字段复制到 Lua table。哪个更快:访问 Lua table 或原始 cdata
变量的字段?
让我们检查一下
使用 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
...
没有 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
...
所以,总结:
- 对于 jit 它们几乎是等价的
- 没有 jit 的表比 ffi 快 20 倍,但是...比有 jit 的表慢 25 倍
在禁用 JIT 的情况下,table 由于 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 是实现字段(即键)查找的方法。
在启用 JIT 的情况下,table 槽和结构字段 addresses/offsets 都专门用于跟踪,在它之前有几个断言守卫。忽略此类断言失败(例如由 table 重新分配导致插槽地址无效),性能差异可以忽略不计。
我看到@mons-anderson 提供的不错的基准测试也证实了这一点。
假设我有一个 cdata
变量(FFI 查询的结果)。然后我将它的字段复制到 Lua table。哪个更快:访问 Lua table 或原始 cdata
变量的字段?
让我们检查一下
使用 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
...
没有 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
...
所以,总结:
- 对于 jit 它们几乎是等价的
- 没有 jit 的表比 ffi 快 20 倍,但是...比有 jit 的表慢 25 倍
在禁用 JIT 的情况下,table 由于 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 是实现字段(即键)查找的方法。
在启用 JIT 的情况下,table 槽和结构字段 addresses/offsets 都专门用于跟踪,在它之前有几个断言守卫。忽略此类断言失败(例如由 table 重新分配导致插槽地址无效),性能差异可以忽略不计。
我看到@mons-anderson 提供的不错的基准测试也证实了这一点。