0

I noticed a severe performance hit, introducing one of my c++ objects as a lua function arg e.g.

function luaFunc(someString)
 print someString
end

this is pretty fast - less than 30ms for 100k calls

now, i added another object

function luaFunc(myCObj, someString)
 print somestring
 myCObj:doStuff()
end

100k calls now take over 1sec. (adding another primitive like int or string as arg has no performance hit! Also, putting the object into global scope (e.g. dont push it each time as func arg, also has no performance hit - but i need it as an argument)

This is how i call it using luabind

 luabind::call_function<void>(fn,myCObj,message);

I was able to reduce the time by 0.5sec by simply using luas pcall function directly - using this "hack":

// this will automatically set the correct class metatable for me
luabind::globals(fn.interpreter())["myCObj"] = myCObj;  
// push my userdata obj onto the stack including the class metatable
lua_getglobal(fn.interpreter(), "myCObj");
lua_pushstring(fn.interpreter(),message);               
lua_pcall(fn.interpreter(), 2, 0,0));       

Still, i think it can be faster and better - this is what i thought doing

void *pUserData = lua_newuserdata( fn.interpreter(), sizeof( MyCClass ) );
pUserData  = myCObj;
lua_getmetatable(fn.interpreter(),????);  
lua_setmetatable( fn.interpreter(), -2 );
lua_pushstring(fn.interpreter(),message);
lua_pcall(fn.interpreter(), 2, 0,0));

So, i believe luabind manages some metatables for each class - but i dont know how to retrieve it - i saw in the source something about "__luabind_classrep" - additionally - in the globals there is a userdata obj with the name i registered my class to luabind.

EDIT: I actually tracked down the initial slow down issue - it was neither luabind nor my code - i was doing the benchmark with VS2010 F5 and it would automatically attach a debugger - for some reason, when adding MyCObj as arg to a lua function - the debugger slowed down the whole processing - i manually ran my command line program from the shell and it was within acceptable margins again (i only recognized this by accident, because a faster computer with the same VS project was taking 4sec instead of 1 which was very unlikely)

Steve
  • 738
  • 1
  • 9
  • 30

1 Answers1

0

Still, i think it can be faster and better - this is what i thought doing

Then stop thinking about that.

There is no guarantee that Luabind uses userdata in that particular way. You certainly don't know that it's userdata is the exact size of the class; it could wrap all C++ objects in some kind of container object.

In short, there's no way to know exactly how Luabind represents a C++ object. Not without looking at Luabind's source (which is subject to change).

In all likelihood, you're getting performance issues due to the constant marshaling of your MyCClass in Luabind. The simplest way to avoid it is to only do the marshaling once. Store the object within Lua using a luabind::object. Just create one with your interpreter and keep it around. Then use that object when you call the method. Luabind won't need to re-marshal the object every time you call the function.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Thanks for your insight - just for reference could you explain how i can convert MyCObj to a luabind object ? And where should i store it - in the registry? (I have multiple of theses). For the original issue - i updated my Q - it was not related to luabind – Steve Jul 10 '12 at 11:22