Optimize imports layout.
This commit is contained in:
parent
81ca86a8d2
commit
61b0c7b2b3
@ -53,7 +53,7 @@ pub const TYPICAL_MAP_SIZE: usize = 8; // Small maps are typical
|
|||||||
// the module name will live beyond the AST of the eval script text.
|
// the module name will live beyond the AST of the eval script text.
|
||||||
// The best we can do is a shared reference.
|
// The best we can do is a shared reference.
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct Imports(StaticVec<(ImmutableString, Shared<Module>)>);
|
pub struct Imports(StaticVec<ImmutableString>, StaticVec<Shared<Module>>);
|
||||||
|
|
||||||
impl Imports {
|
impl Imports {
|
||||||
/// Get the length of this stack of imported [modules][Module].
|
/// Get the length of this stack of imported [modules][Module].
|
||||||
@ -69,7 +69,7 @@ impl Imports {
|
|||||||
/// Get the imported [modules][Module] at a particular index.
|
/// Get the imported [modules][Module] at a particular index.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn get(&self, index: usize) -> Option<Shared<Module>> {
|
pub fn get(&self, index: usize) -> Option<Shared<Module>> {
|
||||||
self.0.get(index).map(|(_, m)| m).cloned()
|
self.1.get(index).cloned()
|
||||||
}
|
}
|
||||||
/// Get the index of an imported [modules][Module] by name.
|
/// Get the index of an imported [modules][Module] by name.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -78,18 +78,19 @@ impl Imports {
|
|||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.rev()
|
.rev()
|
||||||
.find(|(_, (key, _))| key.as_str() == name)
|
.find_map(|(i, key)| if key.as_str() == name { Some(i) } else { None })
|
||||||
.map(|(index, _)| index)
|
|
||||||
}
|
}
|
||||||
/// Push an imported [modules][Module] onto the stack.
|
/// Push an imported [modules][Module] onto the stack.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn push(&mut self, name: impl Into<ImmutableString>, module: impl Into<Shared<Module>>) {
|
pub fn push(&mut self, name: impl Into<ImmutableString>, module: impl Into<Shared<Module>>) {
|
||||||
self.0.push((name.into(), module.into()));
|
self.0.push(name.into());
|
||||||
|
self.1.push(module.into());
|
||||||
}
|
}
|
||||||
/// Truncate the stack of imported [modules][Module] to a particular length.
|
/// Truncate the stack of imported [modules][Module] to a particular length.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn truncate(&mut self, size: usize) {
|
pub fn truncate(&mut self, size: usize) {
|
||||||
self.0.truncate(size);
|
self.0.truncate(size);
|
||||||
|
self.1.truncate(size);
|
||||||
}
|
}
|
||||||
/// Get an iterator to this stack of imported [modules][Module] in reverse order.
|
/// Get an iterator to this stack of imported [modules][Module] in reverse order.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -97,6 +98,7 @@ impl Imports {
|
|||||||
pub fn iter(&self) -> impl Iterator<Item = (&str, &Module)> {
|
pub fn iter(&self) -> impl Iterator<Item = (&str, &Module)> {
|
||||||
self.0
|
self.0
|
||||||
.iter()
|
.iter()
|
||||||
|
.zip(self.1.iter())
|
||||||
.rev()
|
.rev()
|
||||||
.map(|(name, module)| (name.as_str(), module.as_ref()))
|
.map(|(name, module)| (name.as_str(), module.as_ref()))
|
||||||
}
|
}
|
||||||
@ -104,52 +106,44 @@ impl Imports {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn iter_raw(&self) -> impl Iterator<Item = (&ImmutableString, &Shared<Module>)> {
|
pub(crate) fn iter_raw(&self) -> impl Iterator<Item = (&ImmutableString, &Shared<Module>)> {
|
||||||
self.0.iter().rev().map(|(n, m)| (n, m))
|
self.0.iter().rev().zip(self.1.iter().rev())
|
||||||
}
|
}
|
||||||
/// Get an iterator to this stack of imported [modules][Module] in forward order.
|
/// Get an iterator to this stack of imported [modules][Module] in forward order.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn scan_raw(&self) -> impl Iterator<Item = (&ImmutableString, &Shared<Module>)> {
|
pub(crate) fn scan_raw(&self) -> impl Iterator<Item = (&ImmutableString, &Shared<Module>)> {
|
||||||
self.0.iter().map(|(n, m)| (n, m))
|
self.0.iter().zip(self.1.iter())
|
||||||
}
|
}
|
||||||
/// Get a consuming iterator to this stack of imported [modules][Module] in reverse order.
|
/// Get a consuming iterator to this stack of imported [modules][Module] in reverse order.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn into_iter(self) -> impl Iterator<Item = (ImmutableString, Shared<Module>)> {
|
pub fn into_iter(self) -> impl Iterator<Item = (ImmutableString, Shared<Module>)> {
|
||||||
self.0.into_iter().rev()
|
self.0.into_iter().rev().zip(self.1.into_iter().rev())
|
||||||
}
|
|
||||||
/// Add a stream of imported [modules][Module].
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn extend(&mut self, stream: impl Iterator<Item = (ImmutableString, Shared<Module>)>) {
|
|
||||||
self.0.extend(stream)
|
|
||||||
}
|
}
|
||||||
/// Does the specified function hash key exist in this stack of imported [modules][Module]?
|
/// Does the specified function hash key exist in this stack of imported [modules][Module]?
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn contains_fn(&self, hash: u64) -> bool {
|
pub fn contains_fn(&self, hash: u64) -> bool {
|
||||||
self.0.iter().any(|(_, m)| m.contains_qualified_fn(hash))
|
self.1.iter().any(|m| m.contains_qualified_fn(hash))
|
||||||
}
|
}
|
||||||
/// Get specified function via its hash key.
|
/// Get specified function via its hash key.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn get_fn(&self, hash: u64) -> Option<(&CallableFunction, Option<&ImmutableString>)> {
|
pub fn get_fn(&self, hash: u64) -> Option<(&CallableFunction, Option<&ImmutableString>)> {
|
||||||
self.0
|
self.1
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.find_map(|(_, m)| m.get_qualified_fn(hash).map(|f| (f, m.id_raw())))
|
.find_map(|m| m.get_qualified_fn(hash).map(|f| (f, m.id_raw())))
|
||||||
}
|
}
|
||||||
/// Does the specified [`TypeId`][std::any::TypeId] iterator exist in this stack of
|
/// Does the specified [`TypeId`][std::any::TypeId] iterator exist in this stack of
|
||||||
/// imported [modules][Module]?
|
/// imported [modules][Module]?
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn contains_iter(&self, id: TypeId) -> bool {
|
pub fn contains_iter(&self, id: TypeId) -> bool {
|
||||||
self.0.iter().any(|(_, m)| m.contains_qualified_iter(id))
|
self.1.iter().any(|m| m.contains_qualified_iter(id))
|
||||||
}
|
}
|
||||||
/// Get the specified [`TypeId`][std::any::TypeId] iterator.
|
/// Get the specified [`TypeId`][std::any::TypeId] iterator.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn get_iter(&self, id: TypeId) -> Option<IteratorFn> {
|
pub fn get_iter(&self, id: TypeId) -> Option<IteratorFn> {
|
||||||
self.0
|
self.1.iter().rev().find_map(|m| m.get_qualified_iter(id))
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
.find_map(|(_, m)| m.get_qualified_iter(id))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,7 +539,10 @@ impl Engine {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
if !fn_def.mods.is_empty() {
|
if !fn_def.mods.is_empty() {
|
||||||
mods.extend(fn_def.mods.iter_raw().map(|(n, m)| (n.clone(), m.clone())));
|
fn_def
|
||||||
|
.mods
|
||||||
|
.iter_raw()
|
||||||
|
.for_each(|(n, m)| mods.push(n.clone(), m.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate the function
|
// Evaluate the function
|
||||||
|
@ -1836,7 +1836,7 @@ impl Module {
|
|||||||
// Collect a particular module.
|
// Collect a particular module.
|
||||||
fn index_module<'a>(
|
fn index_module<'a>(
|
||||||
module: &'a Module,
|
module: &'a Module,
|
||||||
qualifiers: &mut Vec<&'a str>,
|
path: &mut Vec<&'a str>,
|
||||||
variables: &mut HashMap<u64, Dynamic, StraightHasherBuilder>,
|
variables: &mut HashMap<u64, Dynamic, StraightHasherBuilder>,
|
||||||
functions: &mut HashMap<u64, CallableFunction, StraightHasherBuilder>,
|
functions: &mut HashMap<u64, CallableFunction, StraightHasherBuilder>,
|
||||||
type_iterators: &mut HashMap<TypeId, IteratorFn>,
|
type_iterators: &mut HashMap<TypeId, IteratorFn>,
|
||||||
@ -1845,16 +1845,16 @@ impl Module {
|
|||||||
|
|
||||||
module.modules.iter().for_each(|(name, m)| {
|
module.modules.iter().for_each(|(name, m)| {
|
||||||
// Index all the sub-modules first.
|
// Index all the sub-modules first.
|
||||||
qualifiers.push(name);
|
path.push(name);
|
||||||
if index_module(m, qualifiers, variables, functions, type_iterators) {
|
if index_module(m, path, variables, functions, type_iterators) {
|
||||||
contains_indexed_global_functions = true;
|
contains_indexed_global_functions = true;
|
||||||
}
|
}
|
||||||
qualifiers.pop();
|
path.pop();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Index all variables
|
// Index all variables
|
||||||
module.variables.iter().for_each(|(var_name, value)| {
|
module.variables.iter().for_each(|(var_name, value)| {
|
||||||
let hash_var = crate::calc_fn_hash(qualifiers.iter().map(|&v| v), var_name, 0);
|
let hash_var = crate::calc_fn_hash(path.iter().map(|&v| v), var_name, 0);
|
||||||
variables.insert(hash_var, value.clone());
|
variables.insert(hash_var, value.clone());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1880,15 +1880,12 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !f.func.is_script() {
|
if !f.func.is_script() {
|
||||||
let hash_qualified_fn = calc_native_fn_hash(
|
let hash_qualified_fn =
|
||||||
qualifiers.iter().cloned(),
|
calc_native_fn_hash(path.iter().cloned(), f.name.as_str(), &f.param_types);
|
||||||
f.name.as_str(),
|
|
||||||
&f.param_types,
|
|
||||||
);
|
|
||||||
functions.insert(hash_qualified_fn, f.func.clone());
|
functions.insert(hash_qualified_fn, f.func.clone());
|
||||||
} else if cfg!(not(feature = "no_function")) {
|
} else if cfg!(not(feature = "no_function")) {
|
||||||
let hash_qualified_script =
|
let hash_qualified_script =
|
||||||
crate::calc_fn_hash(qualifiers.iter().cloned(), f.name.as_str(), f.params);
|
crate::calc_fn_hash(path.iter().cloned(), f.name.as_str(), f.params);
|
||||||
functions.insert(hash_qualified_script, f.func.clone());
|
functions.insert(hash_qualified_script, f.func.clone());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1897,16 +1894,16 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !self.indexed {
|
if !self.indexed {
|
||||||
let mut qualifiers = Vec::with_capacity(4);
|
let mut path = Vec::with_capacity(4);
|
||||||
let mut variables = HashMap::with_capacity_and_hasher(16, StraightHasherBuilder);
|
let mut variables = HashMap::with_capacity_and_hasher(16, StraightHasherBuilder);
|
||||||
let mut functions = HashMap::with_capacity_and_hasher(256, StraightHasherBuilder);
|
let mut functions = HashMap::with_capacity_and_hasher(256, StraightHasherBuilder);
|
||||||
let mut type_iterators = HashMap::with_capacity(16);
|
let mut type_iterators = HashMap::with_capacity(16);
|
||||||
|
|
||||||
qualifiers.push("root");
|
path.push("root");
|
||||||
|
|
||||||
self.contains_indexed_global_functions = index_module(
|
self.contains_indexed_global_functions = index_module(
|
||||||
self,
|
self,
|
||||||
&mut qualifiers,
|
&mut path,
|
||||||
&mut variables,
|
&mut variables,
|
||||||
&mut functions,
|
&mut functions,
|
||||||
&mut type_iterators,
|
&mut type_iterators,
|
||||||
|
12
src/token.rs
12
src/token.rs
@ -840,8 +840,8 @@ pub fn parse_string_literal(
|
|||||||
pos: &mut Position,
|
pos: &mut Position,
|
||||||
enclosing_char: char,
|
enclosing_char: char,
|
||||||
) -> Result<String, (LexError, Position)> {
|
) -> Result<String, (LexError, Position)> {
|
||||||
let mut result: StaticVec<char> = Default::default();
|
let mut result: smallvec::SmallVec<[char; 16]> = Default::default();
|
||||||
let mut escape: StaticVec<char> = Default::default();
|
let mut escape: smallvec::SmallVec<[char; 12]> = Default::default();
|
||||||
|
|
||||||
let start = *pos;
|
let start = *pos;
|
||||||
|
|
||||||
@ -1109,7 +1109,7 @@ fn get_next_token_inner(
|
|||||||
|
|
||||||
// digit ...
|
// digit ...
|
||||||
('0'..='9', _) => {
|
('0'..='9', _) => {
|
||||||
let mut result: StaticVec<char> = Default::default();
|
let mut result: smallvec::SmallVec<[char; 16]> = Default::default();
|
||||||
let mut radix_base: Option<u32> = None;
|
let mut radix_base: Option<u32> = None;
|
||||||
let mut valid: fn(char) -> bool = is_numeric_digit;
|
let mut valid: fn(char) -> bool = is_numeric_digit;
|
||||||
result.push(c);
|
result.push(c);
|
||||||
@ -1596,7 +1596,7 @@ fn get_identifier(
|
|||||||
start_pos: Position,
|
start_pos: Position,
|
||||||
first_char: char,
|
first_char: char,
|
||||||
) -> Option<(Token, Position)> {
|
) -> Option<(Token, Position)> {
|
||||||
let mut result: StaticVec<_> = Default::default();
|
let mut result: smallvec::SmallVec<[char; 8]> = Default::default();
|
||||||
result.push(first_char);
|
result.push(first_char);
|
||||||
|
|
||||||
while let Some(next_char) = stream.peek_next() {
|
while let Some(next_char) = stream.peek_next() {
|
||||||
@ -1691,10 +1691,10 @@ pub fn is_id_continue(x: char) -> bool {
|
|||||||
pub struct MultiInputsStream<'a> {
|
pub struct MultiInputsStream<'a> {
|
||||||
/// Buffered character, if any.
|
/// Buffered character, if any.
|
||||||
buf: Option<char>,
|
buf: Option<char>,
|
||||||
/// The input character streams.
|
|
||||||
streams: StaticVec<Peekable<Chars<'a>>>,
|
|
||||||
/// The current stream index.
|
/// The current stream index.
|
||||||
index: usize,
|
index: usize,
|
||||||
|
/// The input character streams.
|
||||||
|
streams: StaticVec<Peekable<Chars<'a>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputStream for MultiInputsStream<'_> {
|
impl InputStream for MultiInputsStream<'_> {
|
||||||
|
Loading…
Reference in New Issue
Block a user