如何从C ++执行Lua函数而不必每次都找到它们?

时间:2016-06-05 02:41:36

标签: lua evaluation

我是Lua的新手,想弄清楚如何从C ++程序中嵌入/使用它。我有基本的机制,但对尽快执行代码感兴趣。所以我正在加载/编译lua代码(包含多个函数),以后我可以使用。

现在假设我有一个名为'add'的lua函数,我想从C ++调用它。据我所知,我必须使用lua_getglobal()函数,它似乎找到并将“add”的字节码推送到Lua堆栈。我可以消除查找部分,即我可以保留对“add”函数的字节码的引用,以便在需要使用它时可以简单地将其推送到堆栈吗?我不知道当有数千个lua函数时lua_getglobal()有多高效,我也不是过早优化的粉丝,但我正在尝试构建一个硬实时系统(是的,实际的物理期限,而不仅仅是快速)如果我不得不匆忙地称“添加”成千上万次,每次都要寻找这个功能似乎是一种真正的浪费。

另外,为了好奇,实际的字节码是否被推送(即复制)到堆栈或只是对它的引用?我希望后者。

提前致谢

2 个答案:

答案 0 :(得分:4)

  

我可以消除查找部分,即我可以保留对“add”函数的字节码的引用,以便在需要使用它时可以将其简单地推送到堆栈吗?

您可以尝试的一件事是使用luaL_Ref来创建对该函数的引用。 这个引用应该更快访问 - 似乎它使用了一个数字索引表,因此它可能比带有字符串键的哈希表更快。

  

在C中,尽可能使用lua_ref()。 lua_ref()在速度方面与局部变量的行为类似。 - Lua,v4.0之前

     

http://lua-users.org/wiki/OptimisationCodingTips

我尝试做了一些测试,并将10万次重量级的tonumber推到堆叠,结果是lua_getglobal用了24秒,rawgeti用ref花了12秒,2个堆栈和lua_pushvalue + lua_xmove用了11秒并使用了lua_pushvalue和相同的状态和堆栈顶部的实际功能需要6秒。 请参阅此处的代码:http://pastebin.com/n8Q0uVx1

http://www.lua.org/manual/5.3/manual.html#luaL_ref http://www.lua.org/manual/5.3/manual.html#luaL_unref

答案 1 :(得分:2)

lua_getglobal,其核心就是进行表查找,功能与执行lua_getfield没有区别。 Lua表是哈希表,因此无论条目数如何,查找都是按照常量时间分摊的。

这并不意味着这种提取超快。但是,获取或多或少的性能并不取决于表中有多少不同的项目。

至于能否将功能存储在某处以便更快地访问...没有。好吧,不合理。

Lua值无法存储在C代码中。虽然您可以从Lua值中获取数字或字符串,但您无法以任何有意义的方式获得Lua函数。您可以拨打lua_topointer,但无法撤消该转化。

但是,您可以做的是从主要的创建子公司lua_State。然后,您将使用函数加载其堆栈。使用堆栈索引比执行散列表查找更快。当需要调用此函数时,您可以使用lua_xmove将函数从子公司lua_State移动到要执行的主状态。

当然,这样做会使您的代码更难以阅读。简单lua_getglobal(L, "add")lua_pushvalue(Funcs, some_int)/lua_xmove(L, Funcs)调用更有意义。使用全局表还允许您更改该值,从而导致对它的所有访问以生成新函数。

此外,还不清楚允许lua_State堆栈的大小。所以你可能没有足够的空间来完成这项工作。

最后,访问函数不会复制实际内存。但是将垃圾收集对象放在堆栈上意味着必须更新其GC数据以注意它正被堆栈引用。所以它不仅仅是一个指针副本。