Optimize MultiValue allocations (recycle old container)

This commit is contained in:
Alex Orlenko 2021-11-12 10:55:20 +00:00
parent 6d689c35aa
commit 2c7d7117d2
No known key found for this signature in database
GPG Key ID: 4C150C250863B96D
3 changed files with 12 additions and 7 deletions

View File

@ -6,7 +6,7 @@ use crate::error::{Error, Result};
use crate::ffi;
use crate::types::LuaRef;
use crate::util::{assert_stack, check_stack, error_traceback, pop_error, StackGuard};
use crate::value::{FromLuaMulti, MultiValue, ToLuaMulti};
use crate::value::{FromLuaMulti, ToLuaMulti};
#[cfg(feature = "async")]
use {futures_core::future::LocalBoxFuture, futures_util::future};
@ -59,7 +59,7 @@ impl<'lua> Function<'lua> {
pub fn call<A: ToLuaMulti<'lua>, R: FromLuaMulti<'lua>>(&self, args: A) -> Result<R> {
let lua = self.0.lua;
let args = args.to_lua_multi(lua)?;
let mut args = args.to_lua_multi(lua)?;
let nargs = args.len() as c_int;
let results = unsafe {
@ -69,7 +69,7 @@ impl<'lua> Function<'lua> {
ffi::lua_pushcfunction(lua.state, error_traceback);
let stack_start = ffi::lua_gettop(lua.state);
lua.push_ref(&self.0);
for arg in args {
for arg in args.drain_all() {
lua.push_value(arg)?;
}
let ret = ffi::lua_pcall(lua.state, nargs, ffi::LUA_MULTRET, stack_start);
@ -77,7 +77,7 @@ impl<'lua> Function<'lua> {
return Err(pop_error(lua.state, ret));
}
let nresults = ffi::lua_gettop(lua.state) - stack_start;
let mut results = MultiValue::new();
let mut results = args; // Recycle MultiValue container
assert_stack(lua.state, 2);
for _ in 0..nresults {
results.push_front(lua.pop_value());

View File

@ -108,7 +108,7 @@ impl<'lua> Thread<'lua> {
R: FromLuaMulti<'lua>,
{
let lua = self.0.lua;
let args = args.to_lua_multi(lua)?;
let mut args = args.to_lua_multi(lua)?;
let nargs = args.len() as c_int;
let results = unsafe {
let _sg = StackGuard::new(lua.state);
@ -123,7 +123,7 @@ impl<'lua> Thread<'lua> {
}
check_stack(thread_state, nargs)?;
for arg in args {
for arg in args.drain_all() {
lua.push_value(arg)?;
}
ffi::lua_xmove(lua.state, thread_state, nargs);
@ -136,7 +136,7 @@ impl<'lua> Thread<'lua> {
return Err(pop_error(thread_state, ret));
}
let mut results = MultiValue::new();
let mut results = args; // Recycle MultiValue container
check_stack(lua.state, nresults + 2)?; // 2 is extra for `lua.pop_value()` below
ffi::lua_xmove(thread_state, lua.state, nresults);

View File

@ -241,6 +241,11 @@ impl<'lua> MultiValue<'lua> {
pub fn iter(&self) -> iter::Rev<slice::Iter<Value<'lua>>> {
self.0.iter().rev()
}
#[inline]
pub(crate) fn drain_all(&mut self) -> iter::Rev<vec::Drain<Value<'lua>>> {
self.0.drain(..).rev()
}
}
/// Trait for types convertible to any number of Lua values.