Lua 栈操作的复杂性(Lua C API)

在 Lua C API 中,它提供了一些栈操作函数,如 Lua 的文档 中所述

int   lua_gettop (lua_State *L);
void  lua_settop (lua_State *L, int index);
void  lua_pushvalue (lua_State *L, int index);
void  lua_remove (lua_State *L, int index);
void  lua_insert (lua_State *L, int index);
void  lua_replace (lua_State *L, int index);

我的第一个问题是,这些函数的复杂度是多少?它是 O(1) 还是 O(|index|)?我查看了 Lua 手册,并且似乎 Lua 有两种不同的栈实现(基于栈和基于寄存器)。

更具体地说,如果我想从 Lua 栈中读取并弹出前三个元素,我可以考虑以下两种实现方式,我能知道哪一种更具性能 / 推荐的方式吗?

解决方案 1--按值读取并弹出:

for (int i = 0; i < 3; ++i) {
  values[i] = lua_tostring(lua_state, -1);
  ...
  lua_pop(lua_state, 1);
}

解决方案 2--先全部读取再全部弹出:

for (int i = 0; i < 3; ++i) {
  values[i] = lua_tostring(lua_state, -1 - i);
}
...
lua_pop(lua_state, 3);
点赞
用户33252
用户33252

Lua 5.3定义中,lua_pop被定义为

#define lua_pop(L,n)            lua_settop(L, -(n)-1)

lua_settop可以在这里看到;它将栈插槽填充为nil,以便值可以设置为gc'd。 因此,具有参数1的时间复杂度为O(1)。

您可以以O(1)读取每个值,且N个值的弹出值为O(N)。

因此,您的两个方法应该大致等同。

关于以O(1)读取值,函数index2addr可以将堆栈偏移量转换为地址。

2016-02-03 01:27:02