Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimizing Lua for cyclic execution

Tags:

lua

I'm exeucting my Lua script once per program cycle of 10 ms. using the same Lua_state (luaL_newstate called once in my app)

Calling luaL_loadbuffer complies the script very fast for sure, still it seems unneccessary to do this every time the script is executed since the script does not change.

Tried to save binary using lua_dump() and then execute it, but lua_pcall() didn't accept the binary for some reason.

Any ideas on how to optimize? (LuaJIT is not an unfortenately an option here)

Jan

like image 743
Jan Ulvesten Avatar asked Jan 05 '14 19:01

Jan Ulvesten


2 Answers

You're correct, if the code is not changing, there is no reason to reprocess the code. Perhaps you could do something like the following:

luaL_loadbuffer(state, buff, len, name); // TODO:  check return value
while (true) {
    // sleep 10ms
    lua_pushvalue(state, -1); // make another reference to the loaded chunk
    lua_call(state, 0, 0);
}

You'll note that we simply duplicate the function reference on the top of the stack, since lua_call removes the function that it calls from the stack. This way, you do not lose a reference to the loaded chunk.

like image 56
Tim Cooper Avatar answered Nov 08 '22 19:11

Tim Cooper


Executing the loadbuffer compiles the script into a chunk of lua code, which you can treat as an anonymous function. The function is put at the top of the stack. You can "save" it the way you would any other value in Lua: push a name for the function onto the stack, then call lua_setglobal(L, name). After that, every time you want to call your function (the chunk), you push it onto the Lua stack, push the parameters onto the stack, and call lua_pcall(L, nargs, nresults). Lua will pop the function and put nresults results onto the stack (regardless of how many results are returned by your function -- if more are returned they are discarded, if fewer then the extras are nil). Example:

int stat = luaL_loadbuffer(L, scriptBuffer, scriptLen, scriptName); 
// check status, if ok save it, else handle error
if (stat == 0) 
    lua_setglobal(L, scriptName);

...

// re-use later: 
lua_getglobal(L, scriptName);
lua_pushinteger(L, 123);
stat = lua_pcall(L, 1, 1, 0);
// check status, if ok get the result off the stack
like image 43
Oliver Avatar answered Nov 08 '22 19:11

Oliver