diff --git a/changes/unreleased/related-features-memo.fixed.md b/changes/unreleased/related-features-memo.fixed.md new file mode 100644 index 0000000000..434deed4c1 --- /dev/null +++ b/changes/unreleased/related-features-memo.fixed.md @@ -0,0 +1 @@ +- The runtime's memo of the features a feature's relationships name, per owner type (#1626), no longer records the features that declare no relationship of the kind asked for, which were most of its entries and grew with every type an instantiation touched. `FeaturesOf` over 7 000 types allocates 285 MB per run instead of 310 MB, and a cold `Instantiate` 230 MB instead of 252 MB, recovering most of what #1626 added over 0.11.0's 273 MB and 221 MB on the same toolchain; the memoized walks of the features that do relate stay memoized, so repeated reads still allocate nothing and `GRPCVerifyConstraint` is unchanged. diff --git a/internal/exec/runtime/subsetting.go b/internal/exec/runtime/subsetting.go index 6d1ac39532..24ad48aa0f 100644 --- a/internal/exec/runtime/subsetting.go +++ b/internal/exec/runtime/subsetting.go @@ -29,6 +29,9 @@ import ( // A declaration that itself restates sym (`:>> elements` on an object, walked past // its library chain) masks nothing on that walk: the target stays the resolved one. func (ctx *Context) relatedFeatures(sym, owner *symbols.Symbol, kind ast.RelationshipKind) []*symbols.Symbol { + if len(ctx.relationshipsOfKind(sym, kind)) == 0 { + return nil + } key := relatedKey{sym, owner, kind} if features, ok := ctx.model.related[key]; ok { return features