【问题标题】:Is accessing a Lua table field faster then accessing a cdata field?访问 Lua 表字段比访问 cdata 字段更快吗?
【发布时间】:2020-09-05 10:57:34
【问题描述】:

假设我有一个cdata 变量(FFI 查询的结果)。然后我将其字段复制到 Lua 表中。哪个更快:访问 Lua 表或原始 cdata 变量的字段?

【问题讨论】:

    标签: lua luajit


    【解决方案1】:

    让我们检查一下

    使用 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 倍

    【讨论】:

      【解决方案2】:

      在禁用 JIT 的情况下,由于 LuaJIT 表 internal structure 和冲突处理优化(例如 Brent 的变体),表键查找的速度要快得多。对于cdata TGETS/TGETV 意味着元方法查找及其进一步执行。 Here 是实现字段(即键)查找的方法。

      启用 JIT 后,表槽和结构字段地址/偏移量都专门用于跟踪,前面有几个断言保护。省略此类断言失败(例如由表重新分配导致的槽地址失效),性能差异可以认为可以忽略不计。

      我看到 @mons-anderson 的不错的基准测试也证实了这一点。

      【讨论】:

      • cdata 的非 JIT 案例实际上也是 cdata 中声明字段的linked list walk,并对每个字段进行字符串指针比较,直到找到匹配的字段。
      猜你喜欢
      • 1970-01-01
      • 2014-11-10
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 2012-10-11
      • 2014-06-25
      • 2020-10-29
      • 1970-01-01
      相关资源
      最近更新 更多