Skip to content

Commit 15e3485

Browse files
bwilkersonCommit Queue
authored andcommitted
Display the sizes of the largest library cycles in the diagnostic pages
I know there it has been hypothesized that large library cycles might be causing some of the performance issues that users are seeing. This CL adds a way for users to be able to tell us how big their library cycles really are, which might help us determine whether that's true. Change-Id: I5cb53f175823dd20a7ff678468b19a6187584b71 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/423206 Reviewed-by: Konstantin Shcheglov <[email protected]> Commit-Queue: Brian Wilkerson <[email protected]>
1 parent 046199b commit 15e3485

File tree

1 file changed

+45
-1
lines changed

1 file changed

+45
-1
lines changed

pkg/analysis_server/lib/src/status/diagnostics.dart

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'dart:async';
66
import 'dart:convert' show JsonEncoder;
77
import 'dart:developer' as developer;
88
import 'dart:io';
9+
import 'dart:math' as math;
910

1011
import 'package:analysis_server/protocol/protocol_constants.dart'
1112
show PROTOCOL_VERSION;
@@ -33,6 +34,8 @@ import 'package:analyzer/dart/analysis/results.dart';
3334
import 'package:analyzer/src/context/source.dart';
3435
import 'package:analyzer/src/dart/analysis/analysis_options_map.dart';
3536
import 'package:analyzer/src/dart/analysis/driver.dart';
37+
import 'package:analyzer/src/dart/analysis/file_state.dart';
38+
import 'package:analyzer/src/dart/analysis/library_graph.dart';
3639
import 'package:analyzer/src/dart/sdk/sdk.dart';
3740
import 'package:analyzer/src/generated/source.dart';
3841
import 'package:analyzer/src/source/package_map_resolver.dart';
@@ -1014,7 +1017,8 @@ class ContextsPage extends DiagnosticPageWithNav {
10141017
'contexts',
10151018
'Contexts',
10161019
description:
1017-
'An analysis context defines the options and the set of sources being analyzed.',
1020+
'An analysis context defines a set of sources for which URIs are '
1021+
'all resolved in the same way.',
10181022
);
10191023

10201024
@override
@@ -1190,6 +1194,41 @@ class ContextsPage extends DiagnosticPageWithNav {
11901194
buf.write('<p class="scroll-table">');
11911195
writeMap(info.templateMap);
11921196
buf.write('</p>');
1197+
1198+
h3('Largest library cycles');
1199+
Set<LibraryCycle> cycles = {};
1200+
var contextRoot = driver.analysisContext!.contextRoot;
1201+
for (var filePath in contextRoot.analyzedFiles()) {
1202+
var fileState = driver.fsState.getFileForPath(filePath);
1203+
var kind = fileState.kind;
1204+
if (kind is LibraryFileKind) {
1205+
cycles.add(kind.libraryCycle);
1206+
}
1207+
}
1208+
var sortedCycles =
1209+
cycles.toList()..sort((first, second) => second.size - first.size);
1210+
var cyclesToDisplay = math.min(sortedCycles.length, 10);
1211+
var initialPathLength = contextRoot.root.path.length + 1;
1212+
buf.write('<p>There are ${sortedCycles.length} library cycles. ');
1213+
buf.write('The $cyclesToDisplay largest contain</p>');
1214+
buf.write('<ul>');
1215+
for (var i = 0; i < cyclesToDisplay; i++) {
1216+
var cycle = sortedCycles[i];
1217+
var libraries = cycle.libraries;
1218+
var cycleSize = cycle.size;
1219+
var libraryCount = math.min(cycleSize, 8);
1220+
buf.write('<li>$cycleSize libraries, including');
1221+
buf.write('<ul>');
1222+
for (var j = 0; j < libraryCount; j++) {
1223+
var library = libraries[j];
1224+
buf.write('<li>');
1225+
buf.write(library.file.path.substring(initialPathLength));
1226+
buf.write('</li>');
1227+
}
1228+
buf.write('</ul>');
1229+
buf.write('</li>');
1230+
}
1231+
buf.write('</ul>');
11931232
}
11941233

11951234
void writeList<E>(List<E> list) {
@@ -2360,6 +2399,11 @@ class _CollectedOptionsData {
23602399
final Set<String> plugins = <String>{};
23612400
}
23622401

2402+
extension on LibraryCycle {
2403+
/// The number of libraries in the cycle.
2404+
int get size => libraries.length;
2405+
}
2406+
23632407
extension on String {
23642408
String get wordBreakOnSlashes => splitMapJoin('/', onMatch: (_) => '/<wbr>');
23652409
}

0 commit comments

Comments
 (0)