Add functions lookup cache.
This commit is contained in:
parent
db7b9cb0f9
commit
d73f3a1d60
@ -24,7 +24,7 @@ use crate::stdlib::{
|
|||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
};
|
};
|
||||||
use crate::syntax::CustomSyntax;
|
use crate::syntax::CustomSyntax;
|
||||||
use crate::utils::get_hasher;
|
use crate::utils::{get_hasher, StraightHasherBuilder};
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_native_fn_hash, Dynamic, EvalAltResult, FnPtr, ImmutableString, Module, Position, Scope,
|
calc_native_fn_hash, Dynamic, EvalAltResult, FnPtr, ImmutableString, Module, Position, Scope,
|
||||||
Shared, StaticVec,
|
Shared, StaticVec,
|
||||||
@ -476,7 +476,7 @@ impl<T: Into<Dynamic>> From<T> for Target<'_> {
|
|||||||
/// ## WARNING
|
/// ## WARNING
|
||||||
///
|
///
|
||||||
/// This type is volatile and may change.
|
/// This type is volatile and may change.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Hash, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct State {
|
pub struct State {
|
||||||
/// Normally, access to variables are parsed with a relative offset into the scope to avoid a lookup.
|
/// Normally, access to variables are parsed with a relative offset into the scope to avoid a lookup.
|
||||||
/// In some situation, e.g. after running an `eval` statement, subsequent offsets become mis-aligned.
|
/// In some situation, e.g. after running an `eval` statement, subsequent offsets become mis-aligned.
|
||||||
@ -489,6 +489,8 @@ pub struct State {
|
|||||||
pub operations: u64,
|
pub operations: u64,
|
||||||
/// Number of modules loaded.
|
/// Number of modules loaded.
|
||||||
pub modules: usize,
|
pub modules: usize,
|
||||||
|
/// Cached lookup values for function hashes.
|
||||||
|
pub functions_cache: HashMap<u64, Option<CallableFunction>, StraightHasherBuilder>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
@ -1886,6 +1888,10 @@ impl Engine {
|
|||||||
});
|
});
|
||||||
|
|
||||||
scope.rewind(prev_scope_len);
|
scope.rewind(prev_scope_len);
|
||||||
|
if mods.len() != prev_mods_len {
|
||||||
|
// If imports list is modified, clear the functions lookup cache
|
||||||
|
state.functions_cache.clear();
|
||||||
|
}
|
||||||
mods.truncate(prev_mods_len);
|
mods.truncate(prev_mods_len);
|
||||||
state.scope_level -= 1;
|
state.scope_level -= 1;
|
||||||
|
|
||||||
@ -2365,6 +2371,8 @@ impl Engine {
|
|||||||
} else {
|
} else {
|
||||||
mods.push(name_def.name.clone(), module);
|
mods.push(name_def.name.clone(), module);
|
||||||
}
|
}
|
||||||
|
// When imports list is modified, clear the functions lookup cache
|
||||||
|
state.functions_cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
state.modules += 1;
|
state.modules += 1;
|
||||||
|
@ -170,14 +170,25 @@ impl Engine {
|
|||||||
) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
||||||
self.inc_operations(state)?;
|
self.inc_operations(state)?;
|
||||||
|
|
||||||
// Search for the native function
|
let func = state.functions_cache.get(&hash_fn).cloned();
|
||||||
// First search registered functions (can override packages)
|
|
||||||
// Then search packages
|
let func = if let Some(ref f) = func {
|
||||||
let func = //lib.get_fn(hash_fn, pub_only)
|
f.as_ref()
|
||||||
self.global_namespace.get_fn(hash_fn, pub_only)
|
} else {
|
||||||
|
// Search for the native function
|
||||||
|
// First search registered functions (can override packages)
|
||||||
|
// Then search packages
|
||||||
|
// lib.get_fn(hash_fn, pub_only)
|
||||||
|
let f = self
|
||||||
|
.global_namespace
|
||||||
|
.get_fn(hash_fn, pub_only)
|
||||||
.or_else(|| self.packages.get_fn(hash_fn))
|
.or_else(|| self.packages.get_fn(hash_fn))
|
||||||
.or_else(|| mods.get_fn(hash_fn));
|
.or_else(|| mods.get_fn(hash_fn));
|
||||||
|
|
||||||
|
state.functions_cache.insert(hash_fn, f.cloned());
|
||||||
|
f
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(func) = func {
|
if let Some(func) = func {
|
||||||
assert!(func.is_native());
|
assert!(func.is_native());
|
||||||
|
|
||||||
@ -370,6 +381,9 @@ impl Engine {
|
|||||||
let mut lib_merged: StaticVec<_>;
|
let mut lib_merged: StaticVec<_>;
|
||||||
|
|
||||||
let unified_lib = if let Some(ref env_lib) = fn_def.lib {
|
let unified_lib = if let Some(ref env_lib) = fn_def.lib {
|
||||||
|
// If the library is modified, clear the functions lookup cache
|
||||||
|
state.functions_cache.clear();
|
||||||
|
|
||||||
lib_merged = Default::default();
|
lib_merged = Default::default();
|
||||||
lib_merged.push(env_lib.as_ref());
|
lib_merged.push(env_lib.as_ref());
|
||||||
lib_merged.extend(lib.iter().cloned());
|
lib_merged.extend(lib.iter().cloned());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user