diff --git a/build_runner/CHANGELOG.md b/build_runner/CHANGELOG.md index 016c6a7076..f1a0bb8d8a 100644 --- a/build_runner/CHANGELOG.md +++ b/build_runner/CHANGELOG.md @@ -1,5 +1,7 @@ ## 2.10.3-wip +- Performance: improve scalability with the number of library cycles, making + builds much faster for some large codebases. - Bug fix: fix crash when you run `dart run build_runner build` in a subdirectory of a package. - Bug fix: in a workspace, generate for transitive dependencies of the current diff --git a/build_runner/lib/src/build/library_cycle_graph/library_cycle_graph_loader.dart b/build_runner/lib/src/build/library_cycle_graph/library_cycle_graph_loader.dart index a734abd441..f4680a7323 100644 --- a/build_runner/lib/src/build/library_cycle_graph/library_cycle_graph_loader.dart +++ b/build_runner/lib/src/build/library_cycle_graph/library_cycle_graph_loader.dart @@ -341,24 +341,21 @@ class LibraryCycleGraphLoader { /// /// A [_graphs] entry will be created for each ID in [newCycles]. void _buildGraphs(int phase, {required List newCycles}) { - // Build lookup from ID to [LibraryCycle] including new and existing cycles. - final existingCycles = []; - for (final phasedCycle in _cycles.values) { - if (phasedCycle.isExpiredAt(phase: phase)) continue; - existingCycles.add(phasedCycle.valueAt(phase: phase)); - } + // Cycles by ID at the current phase. final cycleById = {}; - for (final cycle in existingCycles) { - for (final id in cycle.ids) { - cycleById[id] = cycle; - } - } for (final cycle in newCycles) { for (final id in cycle.ids) { cycleById[id] = cycle; } } + /// Lookups up [id] in [cycleById], falling back to [_cycles] if it's not + /// present. + LibraryCycle lookupLibraryCycle(AssetId id) => + cycleById.putIfAbsent(id, () { + return _cycles[id]!.valueAt(phase: phase); + }); + // Create the graph for each cycle in [newCycles]. for (final root in newCycles) { final graph = LibraryCycleGraphBuilder()..root.replace(root); @@ -379,7 +376,7 @@ class LibraryCycleGraphLoader { for (final id in root.ids) { final assetDeps = _assetDeps[id]!.valueAt(phase: phase); for (final dep in assetDeps.deps) { - final depCycle = cycleById[dep]!; + final depCycle = lookupLibraryCycle(dep); if (identical(depCycle, root)) continue; if (alreadyAddedChildren.add(depCycle)) { final childGraph = _graphs[dep]!.expiringValueAt(phase: phase);