From 05a18cc4cb5960230694fd9631d61431b71703c9 Mon Sep 17 00:00:00 2001 From: Andrew Scott Date: Fri, 15 Nov 2019 13:01:50 -0800 Subject: [PATCH] perf(ivy): R3TestBed - Do not process NgModuleDefs that have already been processed (#33863) PR Close #33863 --- .../core/testing/src/r3_test_bed_compiler.ts | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/packages/core/testing/src/r3_test_bed_compiler.ts b/packages/core/testing/src/r3_test_bed_compiler.ts index b6a832ff30..a1428055d6 100644 --- a/packages/core/testing/src/r3_test_bed_compiler.ts +++ b/packages/core/testing/src/r3_test_bed_compiler.ts @@ -486,17 +486,29 @@ export class R3TestBedCompiler { } private queueTypesFromModulesArray(arr: any[]): void { - for (const value of arr) { - if (Array.isArray(value)) { - this.queueTypesFromModulesArray(value); - } else if (hasNgModuleDef(value)) { - const def = value.ɵmod; - // Look through declarations, imports, and exports, and queue everything found there. - this.queueTypeArray(maybeUnwrapFn(def.declarations), value); - this.queueTypesFromModulesArray(maybeUnwrapFn(def.imports)); - this.queueTypesFromModulesArray(maybeUnwrapFn(def.exports)); + // Because we may encounter the same NgModule while processing the imports and exports of an + // NgModule tree, we cache them in this set so we can skip ones that have already been seen + // encountered. In some test setups, this caching resulted in 10X runtime improvement. + const processedNgModuleDefs = new Set(); + const queueTypesFromModulesArrayRecur = (arr: any[]): void => { + for (const value of arr) { + if (Array.isArray(value)) { + queueTypesFromModulesArrayRecur(value); + } else if (hasNgModuleDef(value)) { + const def = value.ɵmod; + if (processedNgModuleDefs.has(def)) { + continue; + } + processedNgModuleDefs.add(def); + // Look through declarations, imports, and exports, and queue + // everything found there. + this.queueTypeArray(maybeUnwrapFn(def.declarations), value); + queueTypesFromModulesArrayRecur(maybeUnwrapFn(def.imports)); + queueTypesFromModulesArrayRecur(maybeUnwrapFn(def.exports)); + } } - } + }; + queueTypesFromModulesArrayRecur(arr); } private maybeStoreNgDef(prop: string, type: Type) {