如何从 C++ 执行 Lua 函数而不必每次都找到它们?
How can I execute Lua functions from C++ without having to find them each time?
我是 Lua 的新手,想知道如何从 C++ 程序中 embed/use 它。我有基本的机制,但对尽可能快地执行代码感兴趣。所以我是loading/compilinglua代码(包含多个函数)以后可以用
现在假设我有一个名为 'add' 的 lua 函数,我想从 C++ 调用它。据我所知,我必须使用 lua_getglobal() 函数,它似乎可以找到 'add' 的字节码并将其推送到 Lua 堆栈。我可以删除查找部分吗,即我可以保留对函数 'add' 的字节码的引用,以便在我需要使用它时可以简单地将它压入堆栈吗?我不知道当有成千上万个 lua 函数时 lua_getglobal() 的效率如何,我也不喜欢过早优化,但我正在尝试构建一个硬实时系统(是的,实际的物理截止日期,不仅仅是快)而且如果我不得不匆忙调用 'add' 数十万次,那么每次都必须查找函数似乎是一种真正的浪费。
此外,出于好奇,实际的字节码是被推送(即复制)到堆栈上还是只是对它的引用?我希望是后者。
提前致谢
lua_getglobal
的核心只是进行 table 查找,在功能上与 lua_getfield
没有区别。 Lua tables 是散列tables,因此无论条目数多少,查找都是摊销常数时间。
这并不意味着此类提取速度超快。但是获取 more-or-less 的性能并不取决于 table.
中有多少不同的项目
至于能够将函数存储在某个地方以便更快地访问...不。嗯,不合理。
Lua 值不能存储在 C 代码中。虽然您可以从 Lua 值中获取数字或字符串,但您无法以任何有意义的方式获取 Lua 函数。您可以调用 lua_topointer
,但无法撤消该转换。
但是,您可以 做的是从主要的 lua_State
创建一个附属的。然后,您将使用函数加载其 堆栈 。使用堆栈索引比执行哈希-table 查找更快。当需要调用此函数时,您将使用 lua_xmove
将函数从子 lua_State
移动到要执行的主状态。
当然,这样做会使您的代码更难阅读。一个简单的 lua_getglobal(L, "add")
比 lua_pushvalue(Funcs, some_int)/lua_xmove(L, Funcs)
调用更有意义。使用全局 table 还允许您 更改 该值,导致对其的所有访问都产生一个新函数。
此外,还不清楚 lua_State
的堆栈可以有多大。所以你可能没有足够的 space 来完成这项工作。
最后,访问函数不会复制实际内存。但是把一个垃圾收集对象放到栈上就意味着它的GC数据要更新,注意它正在被栈引用。所以它不仅仅是一个指针副本。
Can I eliminate the finding part, i.e. can I keep a reference to the bytecode for the function 'add' so that I can simply push it on to the stack when I need to use it?
您可以尝试的一件事是使用 luaL_Ref 创建对该函数的引用。
这个引用应该可以更快地访问——似乎它使用了一个索引为 table 的数字,所以它可能比使用字符串键的散列 table 更快。
In C, use lua_ref() wherever possible. lua_ref() behaves similarly to a local variable in terms of speed. - Lua, pre v4.0
我尝试做一些测试,并将 tonumber 的 1000000000 次迭代推入堆栈,结果是 lua_getglobal 花费了 24 秒,带有 ref 的 rawgeti 花费了 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
我是 Lua 的新手,想知道如何从 C++ 程序中 embed/use 它。我有基本的机制,但对尽可能快地执行代码感兴趣。所以我是loading/compilinglua代码(包含多个函数)以后可以用
现在假设我有一个名为 'add' 的 lua 函数,我想从 C++ 调用它。据我所知,我必须使用 lua_getglobal() 函数,它似乎可以找到 'add' 的字节码并将其推送到 Lua 堆栈。我可以删除查找部分吗,即我可以保留对函数 'add' 的字节码的引用,以便在我需要使用它时可以简单地将它压入堆栈吗?我不知道当有成千上万个 lua 函数时 lua_getglobal() 的效率如何,我也不喜欢过早优化,但我正在尝试构建一个硬实时系统(是的,实际的物理截止日期,不仅仅是快)而且如果我不得不匆忙调用 'add' 数十万次,那么每次都必须查找函数似乎是一种真正的浪费。
此外,出于好奇,实际的字节码是被推送(即复制)到堆栈上还是只是对它的引用?我希望是后者。
提前致谢
lua_getglobal
的核心只是进行 table 查找,在功能上与 lua_getfield
没有区别。 Lua tables 是散列tables,因此无论条目数多少,查找都是摊销常数时间。
这并不意味着此类提取速度超快。但是获取 more-or-less 的性能并不取决于 table.
中有多少不同的项目至于能够将函数存储在某个地方以便更快地访问...不。嗯,不合理。
Lua 值不能存储在 C 代码中。虽然您可以从 Lua 值中获取数字或字符串,但您无法以任何有意义的方式获取 Lua 函数。您可以调用 lua_topointer
,但无法撤消该转换。
但是,您可以 做的是从主要的 lua_State
创建一个附属的。然后,您将使用函数加载其 堆栈 。使用堆栈索引比执行哈希-table 查找更快。当需要调用此函数时,您将使用 lua_xmove
将函数从子 lua_State
移动到要执行的主状态。
当然,这样做会使您的代码更难阅读。一个简单的 lua_getglobal(L, "add")
比 lua_pushvalue(Funcs, some_int)/lua_xmove(L, Funcs)
调用更有意义。使用全局 table 还允许您 更改 该值,导致对其的所有访问都产生一个新函数。
此外,还不清楚 lua_State
的堆栈可以有多大。所以你可能没有足够的 space 来完成这项工作。
最后,访问函数不会复制实际内存。但是把一个垃圾收集对象放到栈上就意味着它的GC数据要更新,注意它正在被栈引用。所以它不仅仅是一个指针副本。
Can I eliminate the finding part, i.e. can I keep a reference to the bytecode for the function 'add' so that I can simply push it on to the stack when I need to use it?
您可以尝试的一件事是使用 luaL_Ref 创建对该函数的引用。 这个引用应该可以更快地访问——似乎它使用了一个索引为 table 的数字,所以它可能比使用字符串键的散列 table 更快。
In C, use lua_ref() wherever possible. lua_ref() behaves similarly to a local variable in terms of speed. - Lua, pre v4.0
我尝试做一些测试,并将 tonumber 的 1000000000 次迭代推入堆栈,结果是 lua_getglobal 花费了 24 秒,带有 ref 的 rawgeti 花费了 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