5

所有非本地lua对象都存储在某个表中。从表中检索对象通常意味着首先对键进行哈希计算,然后检索相应的对象。我想避免哈希计算的额外步骤。

最简单的事情(曾经可能)是:

lua_Object o(...some lua call...);
lua_pushobject(o);

但是,如前所述,这不再可能了。那么,我怎样才能快速存储一个lua对象(特别是一个大表,重新创建会很慢)然后将其推送到lua堆栈上?我知道注册表,但这只是另一个表,如果我从那里存储/检索,则不会避免哈希计算。

编辑:

一些细节:

包装库的著名问题之一lua是临时表问题。说我打电话:

control:camera():get_something_else()

control带有 CFunction 的表(包装的 C++ 对象)在哪里。camera每次调用该方法时都会返回一个表(另一个包装的 C++ 对象)。如果我们可以缓存这个表,那就太好了,这样就不需要每次都重新创建它,因为时间很关键(出于性能原因,我们使用 C/C++)。此外,我们不想从另一个表中查找该表,因为这意味着计算某个键的哈希值(例如将包装的 C++ 对象的实例强制转换为整数),以及其他查找成本。我的目标是最新lua版本 5.2。

4

2 回答 2

4

我已经用一个可以缓存 CFunction 的结果的上值解决了这个问题;这包括一张桌子。CFunction 可以检查 upvalue 中是否已经存在非 nil 值。如果是这样,它只能重用现有的(向上)值。访问 upvalue 不涉及任何冗长的查找。我不会接受这个答案,因为我最初提出了这个问题并希望鼓励其他答案。

于 2013-11-07T19:29:11.070 回答
2

实际上,在推送和对象时不会计算哈希值。表在添加或删除它的元素时被重新散列

lobject.h

#define setobj(L,obj1,obj2) \
 { const TValue *o2=(obj2); TValue *o1=(obj1); \
   o1->value = o2->value; o1->tt=o2->tt; \
     checkliveness(G(L),o1); }

如果您已经填充了Table对象 ( lobject.h),您可以轻松地复制它们并用它们填充不同的 Lua 虚拟机。宏(从相同lobject.h的设置TValue值到 Your Table

#define sethvalue(L,obj,x) \
  { TValue *i_o=(obj); \
    i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
      checkliveness(G(L),i_o); }

唯一的事情...您将离开公共 Lua C Api 的边界... :)

您可能还需要检查ltable.cand lstate.h。也许稍后会尝试制作一个合适的代码示例......

编辑:另外,如果您想显着减少重新哈希计数,请lua_createtable(lua_State *L, int narr, int nrec);改用... :)

于 2013-11-07T09:22:42.177 回答