Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fast retrieval of lua objects from C/C++

Tags:

c++

c

lua

All non-local lua objects are stored in some table. Retrieving objects from a table usually means a hash calculation of a key is made first and then the corresponding object retrieved. I'd like to avoid the extra step of hash calculation.

The easiest thing (as was once possible) would be:

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

But, as mentioned, this is not possible anymore. So, how can I store and then push a lua object (specifically, a large table, that would be slow to recreate) onto the lua stack quickly? I know about the registry, but that is just another table, the hash calculation is not avoided, if I store/retrieve from there.

EDIT:

Some details:

One of the well-known problems of lua wrapper libraries is the temporary table problem. Say I call:

control:camera():get_something_else()

Where control is a table (wrapped C++ object) with CFunctions. The method camera will return a table (another wrapped C++ object) each time it is called. It would be nice, if we could cache this table, so it would not need to be recreated each time, as time is critical (we use C/C++ for performance reasons). Also we don't want to look the table up from another table, as this implies the calculation of the hash of some key (say the instance of the wrapped C++ object cast to an integer), as well as other look up costs. I am aiming at the latest lua version 5.2.

like image 989
user1095108 Avatar asked Nov 07 '13 08:11

user1095108


2 Answers

I've solved the problem with an upvalue into which the result of a CFunction can be cached; this includes a table. The CFunction can check whether a non-nil value already exists in the upvalue. If so, it can merely reuse the existing (up)value. Access to the upvalue does not involve any lengthy look ups. I won't accept this answer, since I've originally asked the question and would like to encourage other answers.

like image 174
user1095108 Avatar answered Sep 18 '22 05:09

user1095108


Actually, hash is not being calculated while pushing and object. Table is rehashed when adding or removing it's elements

Look at 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); }

If You had filled Table object (lobject.h) You could easily copy them and populate different Lua Virtual Machines with those. Macros ( from same lobject.h for setting TValue's value to 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); }

Only thing... You're going to leave borders of public Lua C Api waaay behind... :)

You might need to check the ltable.c and lstate.h too. Maybe will try to craft a proper code example later...

EDIT: also, if You'd like to significantly decrease rehash count, use lua_createtable(lua_State *L, int narr, int nrec); instead... :)

like image 28
Kamiccolo Avatar answered Sep 21 '22 05:09

Kamiccolo