diff --git a/Cargo.toml b/Cargo.toml index 395c5c6..cbd4b7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,7 @@ mlua_derive = { version = "=0.6.0", optional = true, path = "mlua_derive" } bstr = { version = "0.2", features = ["std"], default_features = false } once_cell = { version = "1.0" } num-traits = { version = "0.2.14" } +rustc-hash = "1.0" futures-core = { version = "0.3.5", optional = true } futures-task = { version = "0.3.5", optional = true } futures-util = { version = "0.3.5", optional = true } diff --git a/src/lua.rs b/src/lua.rs index 4a255f8..6fbb6df 100644 --- a/src/lua.rs +++ b/src/lua.rs @@ -1,6 +1,5 @@ use std::any::TypeId; use std::cell::{Ref, RefCell, RefMut, UnsafeCell}; -use std::collections::HashMap; use std::ffi::CString; use std::fmt; use std::marker::PhantomData; @@ -9,6 +8,8 @@ use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe, Location}; use std::sync::{Arc, Mutex, RwLock}; use std::{mem, ptr, str}; +use rustc_hash::FxHashMap; + use crate::error::{Error, Result}; use crate::ffi; use crate::function::Function; @@ -63,8 +64,8 @@ pub struct Lua { // Data associated with the Lua. struct ExtraData { - registered_userdata: HashMap, - registered_userdata_mt: HashMap<*const c_void, Option>, + registered_userdata: FxHashMap, + registered_userdata_mt: FxHashMap<*const c_void, Option>, registry_unref_list: Arc>>>, libs: StdLib, @@ -456,8 +457,8 @@ impl Lua { // Create ExtraData let extra = Arc::new(UnsafeCell::new(ExtraData { - registered_userdata: HashMap::new(), - registered_userdata_mt: HashMap::new(), + registered_userdata: FxHashMap::default(), + registered_userdata_mt: FxHashMap::default(), registry_unref_list: Arc::new(Mutex::new(Some(Vec::new()))), ref_thread, libs: StdLib::NONE, @@ -2425,7 +2426,7 @@ impl<'lua, T: AsRef<[u8]> + ?Sized> AsChunk<'lua> for T { } // Creates required entries in the metatable cache (see `util::METATABLE_CACHE`) -pub(crate) fn init_metatable_cache(cache: &mut HashMap) { +pub(crate) fn init_metatable_cache(cache: &mut FxHashMap) { cache.insert(TypeId::of::>>(), 0); cache.insert(TypeId::of::(), 0); cache.insert(TypeId::of::(), 0); diff --git a/src/serde/de.rs b/src/serde/de.rs index c77ca44..09b2b82 100644 --- a/src/serde/de.rs +++ b/src/serde/de.rs @@ -1,9 +1,9 @@ use std::cell::RefCell; -use std::collections::HashSet; use std::os::raw::c_void; use std::rc::Rc; use std::string::String as StdString; +use rustc_hash::FxHashSet; use serde::de::{self, IntoDeserializer}; use crate::error::{Error, Result}; @@ -16,7 +16,7 @@ use crate::value::Value; pub struct Deserializer<'lua> { value: Value<'lua>, options: Options, - visited: Rc>>, + visited: Rc>>, } /// A struct with options to change default deserializer behavior. @@ -86,14 +86,14 @@ impl<'lua> Deserializer<'lua> { Deserializer { value, options, - visited: Rc::new(RefCell::new(HashSet::new())), + visited: Rc::new(RefCell::new(FxHashSet::default())), } } fn from_parts( value: Value<'lua>, options: Options, - visited: Rc>>, + visited: Rc>>, ) -> Self { Deserializer { value, @@ -313,7 +313,7 @@ impl<'lua, 'de> serde::Deserializer<'de> for Deserializer<'lua> { struct SeqDeserializer<'lua> { seq: TableSequence<'lua, Value<'lua>>, options: Options, - visited: Rc>>, + visited: Rc>>, } impl<'lua, 'de> de::SeqAccess<'de> for SeqDeserializer<'lua> { @@ -351,7 +351,7 @@ struct MapDeserializer<'lua> { pairs: TablePairs<'lua, Value<'lua>, Value<'lua>>, value: Option>, options: Options, - visited: Rc>>, + visited: Rc>>, processed: usize, } @@ -407,7 +407,7 @@ struct EnumDeserializer<'lua> { variant: StdString, value: Option>, options: Options, - visited: Rc>>, + visited: Rc>>, } impl<'lua, 'de> de::EnumAccess<'de> for EnumDeserializer<'lua> { @@ -431,7 +431,7 @@ impl<'lua, 'de> de::EnumAccess<'de> for EnumDeserializer<'lua> { struct VariantDeserializer<'lua> { value: Option>, options: Options, - visited: Rc>>, + visited: Rc>>, } impl<'lua, 'de> de::VariantAccess<'de> for VariantDeserializer<'lua> { @@ -499,12 +499,12 @@ impl<'lua, 'de> de::VariantAccess<'de> for VariantDeserializer<'lua> { // Used to track recursive tables but allow to traverse same tables multiple times struct RecursionGuard { ptr: *const c_void, - visited: Rc>>, + visited: Rc>>, } impl RecursionGuard { #[inline] - fn new(table: &Table, visited: &Rc>>) -> Self { + fn new(table: &Table, visited: &Rc>>) -> Self { let visited = Rc::clone(visited); let lua = table.0.lua; let ptr = @@ -524,7 +524,7 @@ impl Drop for RecursionGuard { fn check_value_if_skip( value: &Value, options: Options, - visited: &RefCell>, + visited: &RefCell>, ) -> Result { match value { Value::Table(table) => { diff --git a/src/util.rs b/src/util.rs index 6a4c923..c16c826 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,5 +1,4 @@ use std::any::{Any, TypeId}; -use std::collections::HashMap; use std::error::Error as StdError; use std::fmt::Write; use std::os::raw::{c_char, c_int, c_void}; @@ -8,12 +7,13 @@ use std::sync::Arc; use std::{mem, ptr, slice}; use once_cell::sync::Lazy; +use rustc_hash::FxHashMap; use crate::error::{Error, Result}; use crate::ffi; -static METATABLE_CACHE: Lazy> = Lazy::new(|| { - let mut map = HashMap::with_capacity(32); +static METATABLE_CACHE: Lazy> = Lazy::new(|| { + let mut map = FxHashMap::with_capacity_and_hasher(32, Default::default()); crate::lua::init_metatable_cache(&mut map); map.insert(TypeId::of::(), 0); map.insert(TypeId::of::(), 0);