Files
sdk/pkg/analysis_server/tool/code_completion/benchmark/flutter.dart
T
Konstantin Shcheglov 22873be577 Completion. Benchmark for continuously asking completions.
Useful to focus on measuring performance of computing suggestions
only, without any overhead of resolution, protocol conversion, etc.

To be run as is, or with `--observe:xxxx` to see what to optimize.

You need to supply your own Flutter checkout.

Change-Id: Ie143b4ec9c24e05a0de2a14c1b8f0e1c20ef3a8a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/358222
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
2024-03-18 22:56:10 +00:00

115 lines
3.8 KiB
Dart

// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/file_system/overlay_file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'sliding_statistics.dart';
/// A tool to see the current performance of code completion at an interesting
/// location. To see details, run it with `--observe:5000` and then use
/// DevTools CPU profiler.
///
/// Currently this is not a tool to track performance, it does not record it
/// anywhere.
///
/// Update the marked code as necessary to construct a case for checking
/// performance. The code below is just one example that we saw to have
/// significant cost.
///
/// Don't forget to update [flutterPackagePath].
Future<void> main() async {
await _runForever(
path: '$flutterPackagePath/lib/test.dart',
markedCode: r'''
import 'package:flutter/widgets.dart';
Widget x = ^;
''',
);
}
const String flutterEnvironmentPath =
'/Users/scheglov/dart/flutter_elements/environment';
/// This should be the path of the `package:flutter` in a local checkout.
/// You don't have to use [flutterEnvironmentPath] from above.
const String flutterPackagePath = '$flutterEnvironmentPath/packages/flutter';
Future<void> _runForever({
required String path,
required String markedCode,
}) async {
final offset = markedCode.indexOf('^');
if (offset == -1) {
throw ArgumentError('No ^ marker');
}
final rawCode =
markedCode.substring(0, offset) + markedCode.substring(offset + 1);
if (rawCode.contains('^')) {
throw ArgumentError('Duplicate ^ marker');
}
final resourceProvider = OverlayResourceProvider(
PhysicalResourceProvider.INSTANCE,
);
resourceProvider.setOverlay(
path,
content: rawCode,
modificationStamp: -1,
);
var collection = AnalysisContextCollectionImpl(
resourceProvider: resourceProvider,
includedPaths: [path],
sdkPath: '/Users/scheglov/Applications/dart-sdk',
);
var analysisContext = collection.contextFor(path);
var analysisSession = analysisContext.currentSession;
var unitResult = await analysisSession.getResolvedUnit(path);
unitResult as ResolvedUnitResult;
var dartRequest = DartCompletionRequest.forResolvedUnit(
resolvedUnit: unitResult,
offset: offset,
);
final statistics = SlidingStatistics(100);
while (true) {
var timer = Stopwatch()..start();
var budget = CompletionBudget(Duration(seconds: 30));
List<CompletionSuggestionBuilder> suggestions = [];
for (var i = 0; i < 10; i++) {
suggestions = await DartCompletionManager(
budget: budget,
notImportedSuggestions: NotImportedSuggestions(),
).computeSuggestions(
dartRequest,
OperationPerformanceImpl('<root>'),
useFilter: false,
);
}
final responseTime = timer.elapsedMilliseconds;
statistics.add(responseTime);
if (statistics.isReady) {
print(
'[${DateTime.now().millisecondsSinceEpoch}]'
'[time: $responseTime ms][mean: ${statistics.mean.toStringAsFixed(1)}]'
'[stdDev: ${statistics.standardDeviation.toStringAsFixed(3)}]'
'[min: ${statistics.min.toStringAsFixed(1)}]'
'[max: ${statistics.max.toStringAsFixed(1)}]',
);
} else {
print('[time: $responseTime ms][suggestions: ${suggestions.length}]');
}
}
}