mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 18:58:30 +00:00
perf: cache subtype relation judgement
This commit is contained in:
parent
544fee8d59
commit
c965ea2c5b
5 changed files with 75 additions and 3 deletions
|
@ -260,6 +260,26 @@ impl<K: Eq, V> Dict<K, V> {
|
|||
.find(|(k, _)| (*k).borrow() == key)
|
||||
.map(|(_, v)| v)
|
||||
}
|
||||
|
||||
/// K: interior-mutable
|
||||
/// This method is O(1) but may fail to get the value.
|
||||
pub fn force_o1_get<Q>(&self, key: &Q) -> Option<&V>
|
||||
where
|
||||
K: Borrow<Q> + Hash,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
self.dict.get(key)
|
||||
}
|
||||
|
||||
/// K: interior-mutable
|
||||
/// This method is O(1) but may fail to get the value.
|
||||
pub fn force_o1_get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
|
||||
where
|
||||
K: Borrow<Q> + Hash,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
self.dict.get_mut(key)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Eq, V: Eq> Dict<K, V> {
|
||||
|
|
|
@ -234,12 +234,24 @@ impl Context {
|
|||
/// make judgments that include supertypes in the same namespace & take into account glue patches
|
||||
/// 同一名前空間にある上位型を含めた判定&接着パッチを考慮した判定を行う
|
||||
fn nominal_supertype_of(&self, lhs: &Type, rhs: &Type) -> bool {
|
||||
if let Some(res) = self.shared().type_cache.get(lhs, rhs) {
|
||||
return res.is_subtype;
|
||||
}
|
||||
if let (Absolutely, judge) = self.classes_supertype_of(lhs, rhs) {
|
||||
self.shared()
|
||||
.type_cache
|
||||
.insert(lhs.clone(), rhs.clone(), judge);
|
||||
return judge;
|
||||
}
|
||||
if let (Absolutely, judge) = self.traits_supertype_of(lhs, rhs) {
|
||||
self.shared()
|
||||
.type_cache
|
||||
.insert(lhs.clone(), rhs.clone(), judge);
|
||||
return judge;
|
||||
}
|
||||
self.shared()
|
||||
.type_cache
|
||||
.insert(lhs.clone(), rhs.clone(), false);
|
||||
false
|
||||
}
|
||||
|
||||
|
|
|
@ -2042,8 +2042,8 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
|
|||
return None;
|
||||
}
|
||||
}
|
||||
(FreeVar(fv), _) if fv.is_linked() => return self.unify(&fv.crack(), rhs),
|
||||
(_, FreeVar(fv)) if fv.is_linked() => return self.unify(lhs, &fv.crack()),
|
||||
(FreeVar(fv), _) if fv.is_linked() => return self.unify(&fv.unwrap_linked(), rhs),
|
||||
(_, FreeVar(fv)) if fv.is_linked() => return self.unify(lhs, &fv.unwrap_linked()),
|
||||
// TODO: unify(?T, ?U) ?
|
||||
(FreeVar(_), FreeVar(_)) => {}
|
||||
(FreeVar(fv), _) if fv.constraint_is_sandwiched() => {
|
||||
|
|
|
@ -431,3 +431,39 @@ impl SharedGeneralizationCache {
|
|||
self.0.borrow().linear_get(key).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
use crate::ty::Type;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct TypeRelationResult {
|
||||
pub is_subtype: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct SupAndResult(Dict<Type, TypeRelationResult>);
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct SharedTypeRelationCache(Shared<Dict<Type, SupAndResult>>);
|
||||
|
||||
impl SharedTypeRelationCache {
|
||||
pub fn new() -> Self {
|
||||
Self(Shared::new(Dict::new()))
|
||||
}
|
||||
|
||||
pub fn insert(&self, sub: Type, sup: Type, is_subtype: bool) {
|
||||
self.0
|
||||
.borrow_mut()
|
||||
.entry(sub)
|
||||
.or_default()
|
||||
.0
|
||||
.insert(sup, TypeRelationResult { is_subtype });
|
||||
}
|
||||
|
||||
pub fn get(&self, sub: &Type, sup: &Type) -> Option<TypeRelationResult> {
|
||||
self.0
|
||||
.borrow()
|
||||
.force_o1_get(sub)
|
||||
.and_then(|dict| dict.0.force_o1_get(sup))
|
||||
.copied()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,9 @@ use erg_common::spawn::safe_yield;
|
|||
|
||||
use crate::context::{Context, ModuleContext};
|
||||
|
||||
use super::cache::{ModuleEntry, SharedGeneralizationCache, SharedModuleCache};
|
||||
use super::cache::{
|
||||
ModuleEntry, SharedGeneralizationCache, SharedModuleCache, SharedTypeRelationCache,
|
||||
};
|
||||
use super::errors::{SharedCompileErrors, SharedCompileWarnings};
|
||||
use super::graph::SharedModuleGraph;
|
||||
use super::impls::SharedTraitImpls;
|
||||
|
@ -35,6 +37,7 @@ pub struct SharedCompilerResource {
|
|||
pub errors: SharedCompileErrors,
|
||||
pub warns: SharedCompileWarnings,
|
||||
pub gen_cache: SharedGeneralizationCache,
|
||||
pub type_cache: SharedTypeRelationCache,
|
||||
}
|
||||
|
||||
impl SharedCompilerResource {
|
||||
|
@ -52,6 +55,7 @@ impl SharedCompilerResource {
|
|||
errors: SharedCompileErrors::new(),
|
||||
warns: SharedCompileWarnings::new(),
|
||||
gen_cache: SharedGeneralizationCache::new(),
|
||||
type_cache: SharedTypeRelationCache::new(),
|
||||
};
|
||||
Context::init_builtins(cfg, self_.clone());
|
||||
self_
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue