speed up TraceAsString by caching the canonical type for can_substitute_type

This commit is contained in:
Jacob Lifshay 2026-06-01 20:41:14 -07:00
parent cf3e6cfc6b
commit 1880ed682f
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ

View file

@ -1309,16 +1309,49 @@ trait TraceAsStringTrait: fmt::Debug + 'static + Send + Sync + SupportsPtrEqWith
fn can_substitute_type(&self, new_type: CanonicalType) -> bool;
}
impl<T: Type> TraceAsStringTrait for T {
#[derive(Clone, PartialEq, Eq, Hash)]
struct TraceAsStringState<T: Type> {
ty: Interned<T>,
canonical_ty: CanonicalType,
}
impl<T: Type> TraceAsStringState<T> {
fn new(ty: Interned<T>) -> Interned<Self> {
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
struct MyMemoize<T: Type>(PhantomData<T>);
impl<T: Type> Memoize for MyMemoize<T> {
type Input = Interned<T>;
type InputOwned = Interned<T>;
type Output = Interned<TraceAsStringState<T>>;
fn inner(self, input: &Self::Input) -> Self::Output {
TraceAsStringState {
ty: *input,
canonical_ty: input.canonical(),
}
.intern_sized()
}
}
MyMemoize(PhantomData).get_owned(ty)
}
}
impl<T: Type> fmt::Debug for TraceAsStringState<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.ty.fmt(f)
}
}
impl<T: Type> TraceAsStringTrait for TraceAsStringState<T> {
fn trace_fmt(
&self,
opaque: OpaqueSimValueSlice<'_>,
f: &mut fmt::Formatter<'_>,
) -> fmt::Result {
fmt::Debug::fmt(&Type::sim_value_from_opaque(self, opaque), f)
fmt::Debug::fmt(&Type::sim_value_from_opaque(&*self.ty, opaque), f)
}
fn can_substitute_type(&self, new_type: CanonicalType) -> bool {
self.canonical().is_layout_equivalent(new_type)
self.canonical_ty.is_layout_equivalent(new_type)
}
}
@ -1374,7 +1407,7 @@ impl<T: Type> TraceAsString<T> {
Self {
inner_ty: LazyInterned::Interned(inner_ty),
trace_as_string: LazyInterned::Interned(Interned::cast_unchecked(
inner_ty,
TraceAsStringState::new(inner_ty),
|v| -> &dyn TraceAsStringTrait { v },
)),
}
@ -1548,7 +1581,10 @@ impl<T: StaticType> Default for TraceAsStringStaticTypeHelper<T> {
impl<T: StaticType> From<TraceAsStringStaticTypeHelper<T>> for Interned<dyn TraceAsStringTrait> {
fn from(_value: TraceAsStringStaticTypeHelper<T>) -> Self {
Interned::cast_unchecked(T::TYPE.intern_sized(), |v| -> &dyn TraceAsStringTrait { v })
Interned::cast_unchecked(
TraceAsStringState::new(T::TYPE.intern_sized()),
|v| -> &dyn TraceAsStringTrait { v },
)
}
}