Optimize MultiValue allocations (recycle old container)
This commit is contained in:
parent
6d689c35aa
commit
2c7d7117d2
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue