获取C++对象的类元表以将该对象作为参数推送到Lua函数

我注意到一个严重的性能问题,那就是将我的一个 C++ 对象作为 Lua 函数参数引入,例如:

function luaFunc(someString)
 print someString
end

这非常快——在 10 万个调用中只需不到 30 毫秒

现在,我添加了另一个对象

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

10 万个调用现在需要超过 1 秒(添加另一个原始类型,例如 int 或 string,作为参数并不影响性能!把对象放到全局作用域中(例如不每次将其作为函数参数推入),也不影响性能——但我需要它作为一个参数)

以下是我使用 luabind 进行调用的方式

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

我简单地使用 luas 的 pcall 函数直接减少了 0.5 秒的时间——使用这个“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));

不过,我认为它可以更快,更好——这就是我想要做的:

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));

因此,我相信 luabind 管理每个类的一些元表,但我不知道如何检索它——我在源代码中看到了一些"__luabind_classrep"的内容——此外,在全局区中有一个名为我将类注册到 luabind 中的 userdata 对象。

编辑:我实际上追踪了初步的减速问题——它既不是 luabind 也不是我的代码——我使用了 VS2010 F5 进行批处理,它会自动附加调试器——由于某种原因,当将 MyCObj 添加为 Lua 函数的参数时,调试器会减缓整个处理过程——我从 shell 手动运行了我的命令行程序,它又处于可接受的范围内(我仅仅是偶然发现了这一点,因为使用相同的 VS 项目的更快的电脑花了 4 秒钟而不是 1 秒钟,这是非常不可能的)

点赞
用户734069
用户734069

尽管如此,我认为它可以更快更好 - 这是我想做的事情

那就别再想了。

不能保证 Luabind 以特定的方式使用 userdata。你肯定不知道它的 userdata 是否是该类的确切大小;它可能会将所有 C++ 对象都包装在某种容器对象中。

简而言之,没有办法 确切地 知道 Luabind 如何表示 C++ 对象。没有查看 Luabind 的源代码(这是可能变化的)就不可能知道。

很可能,由于 Luabind 中的 MyCClass 不断进行编组,导致性能受到影响。避免这种情况的最简单方法是只进行一次编组。使用 luabind::object 在 Lua 中存储对象。只需在解释器中创建一个对象并将其保留下来。然后在调用方法时使用该对象。每次调用函数时,Luabind 不必重新编组对象。

2012-07-10 03:42:55