diff options
author | Alex Orlenko <zxteam@protonmail.com> | 2023-06-04 20:53:12 +0100 |
---|---|---|
committer | Alex Orlenko <zxteam@protonmail.com> | 2023-06-04 20:53:12 +0100 |
commit | d5483988d2c81f9850f0854cc58783b64d727855 (patch) | |
tree | 012c4ddc92f46c01b6db1004b2a5d7fcff9c50c2 /src/lua.rs | |
parent | 0f5c68dcf8f46f881150e8c9f648dab7f034625e (diff) | |
download | mlua-d5483988d2c81f9850f0854cc58783b64d727855.zip |
Optimize polling async functions (40% performance win)
Diffstat (limited to 'src/lua.rs')
-rw-r--r-- | src/lua.rs | 52 |
1 files changed, 31 insertions, 21 deletions
@@ -2773,31 +2773,33 @@ impl Lua { unsafe extern "C" fn poll_future(state: *mut ffi::lua_State) -> c_int { let upvalue = get_userdata::<AsyncPollUpvalue>(state, ffi::lua_upvalueindex(1)); let extra = (*upvalue).extra.get(); - callback_error_ext(state, extra, |nargs| { - if nargs < ffi::LUA_MINSTACK { - check_stack(state, ffi::LUA_MINSTACK - nargs)?; - } - + callback_error_ext(state, extra, |_| { let lua: &Lua = mem::transmute((*extra).inner.assume_init_ref()); let _guard = StateGuard::new(&lua.0, state); let fut = &mut (*upvalue).data; let mut ctx = Context::from_waker(lua.waker()); match fut.as_mut().poll(&mut ctx) { - Poll::Pending => { - check_stack(state, 1)?; - ffi::lua_pushboolean(state, 0); - Ok(1) - } + Poll::Pending => Ok(0), Poll::Ready(results) => { - let results = results?; - let nresults = results.len() as Integer; - let results = lua.create_sequence_from(results)?; - check_stack(state, 3)?; - ffi::lua_pushboolean(state, 1); - lua.push_value(Value::Table(results))?; - lua.push_value(Value::Integer(nresults))?; - Ok(3) + let mut results = results?; + let nresults = results.len(); + lua.push_value(Value::Integer(nresults as _))?; + match nresults { + 0 => Ok(1), + 1 | 2 => { + // Fast path for 1 or 2 results without creating a table + for r in results.drain_all() { + lua.push_value(r)?; + } + MultiValue::return_to_pool(results, lua); + Ok(nresults as c_int + 1) + } + _ => { + lua.push_value(Value::Table(lua.create_sequence_from(results)?))?; + Ok(2) + } + } } } }) @@ -2850,9 +2852,17 @@ impl Lua { local poll = get_poll(...) local pending, yield, unpack = pending, yield, unpack while true do - local ready, res, nres = poll() - if ready then - return unpack(res, nres) + local nres, res, res2 = poll() + if nres ~= nil then + if nres == 0 then + return + elseif nres == 1 then + return res + elseif nres == 2 then + return res, res2 + else + return unpack(res, nres) + end end yield(pending) end |