Skip to content

Commit c3fa09f

Browse files
jensjohaCommit Queue
authored andcommitted
[analyzer] E2E benchmark also supports legacy protocol
Also add benchmark where lots of hover requests are fired, mimicking IntelliJ behavior when holding ctrl and moving the mouse over imports. I'm getting these results on my machine: ``` 4 files / CodeType.ImportCycle: Initial analysis: 1.249438 Completion after change: 10.143719 4 files / CodeType.ImportChain: Initial analysis: 1.367604 Completion after change: 9.936909 4 files / CodeType.ImportExportCycle: Initial analysis: 1.233644 Completion after change: 10.011695 4 files / CodeType.ImportExportChain: Initial analysis: 1.226382 Completion after change: 9.875991 4 files / CodeType.ImportCycleExportChain: Initial analysis: 1.262932 Completion after change: 9.995607 ``` notice the low number of files (in the chain*) or if it even is a chain etc doesn't appear to change anything for the time it takes to become responsive again. Notice that in #55281 (comment) I noticed that something similar happened for `edit.getFixes`, but I'm yet to actually reproduce that. Change-Id: Iff04124825c6ea2f759b4d048a0f2988709eaebf Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/413981 Commit-Queue: Jens Johansen <[email protected]> Reviewed-by: Phil Quitslund <[email protected]>
1 parent da1a5b5 commit c3fa09f

File tree

7 files changed

+670
-309
lines changed

7 files changed

+670
-309
lines changed

pkg/analysis_server/tool/benchmark_tools/big_chain_benchmark/big_chain_benchmark.dart

Lines changed: 0 additions & 272 deletions
This file was deleted.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import '../language_server_benchmark.dart';
6+
import '../legacy_messages.dart';
7+
import 'utils.dart';
8+
9+
/// Hovering over an import with ctrl down in IntelliJ sends getHover requests
10+
/// for the import uri at position 0 every ~8 ms and never cancels old requests.
11+
/// This benchmark does this 500 times (roughly equal to hovering for 4 seconds)
12+
/// and reports how long it takes before the analysis server is responsive again
13+
/// (measured by when it responds to a completion request).
14+
Future<void> main() async {
15+
await runHelper(
16+
LegacyManyHoverRequestsBenchmark.new,
17+
runAsLsp: false,
18+
// The number of files doesn't seem to be important on this one.
19+
numberOfFileOptions: [4],
20+
);
21+
}
22+
23+
class LegacyManyHoverRequestsBenchmark extends DartLanguageServerBenchmark {
24+
@override
25+
final Uri rootUri;
26+
@override
27+
final Uri cacheFolder;
28+
29+
final RunDetails runDetails;
30+
31+
LegacyManyHoverRequestsBenchmark(
32+
this.rootUri,
33+
this.cacheFolder,
34+
this.runDetails,
35+
) : super(useLspProtocol: false);
36+
37+
@override
38+
LaunchFrom get launchFrom => LaunchFrom.Dart;
39+
40+
@override
41+
Future<void> afterInitialization() async {
42+
var mainFileLines = runDetails.mainFile.content.split('\n');
43+
if (!mainFileLines[2].startsWith('void main')) throw 'unexpected file data';
44+
if (mainFileLines[3].trim().isNotEmpty) throw 'unexpected file data';
45+
mainFileLines[3] = ' ge';
46+
var newMainFileContent = StringBuffer();
47+
for (int i = 0; i <= 3; i++) {
48+
newMainFileContent.writeln(mainFileLines[i]);
49+
}
50+
var geOffset = newMainFileContent.length - 1;
51+
for (int i = 4; i < mainFileLines.length; i++) {
52+
newMainFileContent.writeln(mainFileLines[i]);
53+
}
54+
55+
await send(
56+
LegacyMessages.setPriorityFiles(largestIdSeen + 1, [
57+
runDetails.mainFile.uri,
58+
]),
59+
);
60+
61+
// Hovering over an import with ctrl down in IntelliJ send getHover for the
62+
// import uri at position 0 every ~8 ms and never cancels old requests.
63+
// 500 times is roughly equal to hovering for 4 seconds.
64+
for (var i = 0; i < 500; i++) {
65+
await send(
66+
LegacyMessages.getHover(
67+
largestIdSeen + 1,
68+
runDetails.orderedFileCopies.first.uri,
69+
0,
70+
),
71+
);
72+
await Future.delayed(const Duration(milliseconds: 8));
73+
}
74+
75+
// Type 'ge' in the empty line in main.
76+
await send(
77+
LegacyMessages.updateContent(
78+
largestIdSeen + 1,
79+
runDetails.mainFile.uri,
80+
newMainFileContent.toString(),
81+
),
82+
);
83+
84+
// Ask for completion
85+
Future<Map<String, dynamic>> completionFuture =
86+
(await send(
87+
LegacyMessages.getSuggestions2(
88+
largestIdSeen + 1,
89+
runDetails.mainFile.uri,
90+
geOffset,
91+
),
92+
))!.completer.future;
93+
94+
Stopwatch stopwatch = Stopwatch()..start();
95+
var completionResponse = await completionFuture;
96+
List<dynamic> completionItems =
97+
completionResponse['result']['suggestions'] as List;
98+
var completionAfterChange = stopwatch.elapsed;
99+
durationInfo.add(
100+
DurationInfo('Completion after change', completionAfterChange),
101+
);
102+
print(
103+
'Got ${completionItems.length} completion items '
104+
'in $completionAfterChange',
105+
);
106+
}
107+
}

0 commit comments

Comments
 (0)