In the Lua C API, it offers couple stack operation functions as mentioned in Lua's document
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);
My first question is, what is the complexity of these function? Is it O(1) or O(|index|)? I checked the Lua manual and it seems Lua has two different implementations of stack (stack based and register based).
More specifically, if I would like to read and pop the top three elements from the lua stack, I can think of the following two implementations, can I know which one is more performant / suggested way?
Solution 1 -- read and pop for each value:
for (int i = 0; i < 3; ++i) {
values[i] = lua_tostring(lua_state, -1);
...
lua_pop(lua_state, 1);
}
Solution 2 -- read all and then pop all:
for (int i = 0; i < 3; ++i) {
values[i] = lua_tostring(lua_state, -1 - i);
}
...
lua_pop(lua_state, 3);
Lua 5.3 defines lua_pop as
#define lua_pop(L,n) lua_settop(L, -(n)-1)
and lua_settop can be seen here; it will fill the stack slots with nil so the values can be gc'd. So it's O(1) with arg 1.
You can read each value in O(1), and the pop of N values is O(N).
So, your two approaches should be roughly equivalent.
Re: reading values in O(1), the function index2addr is what translates a stack offset to an address.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With