Files
Jens Johansen a98011a5ef [analyzer] Initial LSP server e2e benchmark
A benchmark that launches the dart analyzer server in language server
protocol mode and communicates with is as an IDE.
In this case the benchmark generates between 16 and 1024 copies of the
abstract scanner (to get a large amount of code) as well as imports and
exports all the files in cycles and/or chains; performs an edit,
requests completion and times initial startup (with no cache),
completion after change and when it's done analyzing after the change.

It does this in several modes than change the way the files are imported
and exported:
* ImportCycle where file1 imports file2 etc and the last file imports
  file1. There are no exports.
* ImportChain where file1 imports file2 etc and the last file doesn't
  import anything. There are no exports.
* ImportExportCycle where file1 imports and exports file2 etc and the
  last file imports and exports file1.
* ImportExportChain where file1 imports and exports file2 etc and the
  last file doesn't import or export anything.
* ImportCycleExportChain where file1 imports and exports file2 etc and
  the last file imports file1 but doesn't export anything.

For ImportCycle, ImportChain and ImportExportChain things appear to
scale ~linear and - using AOT - have timeings in this ballpark (this is
specifically for ImportCycle):

+------+-----------+------------+------------+
| Size |  Initial  | Completion | Fully done |
+------+-----------+------------+------------+
|   16 |   0.46561 |   0.158765 |    0.40474 |
|   32 |  0.901167 |   0.268819 |   0.859874 |
|   64 |  1.657207 |   0.428747 |   1.488365 |
|  128 |  3.178606 |   0.843576 |   3.040237 |
|  256 |  6.015557 |   1.737661 |   6.010487 |
|  512 |  12.08567 |   2.979242 |  11.736878 |
| 1024 | 24.273368 |   6.101671 |  24.018495 |
+------+-----------+------------+------------+

For ImportExportCycle and ImportCycleExportChain it scales worse and
e.g. ImportExportCycle looks like this:

+------+-----------+------------+------------+
| Size |  Initial  | Completion | Fully done |
+------+-----------+------------+------------+
|   16 |   0.46673 |   0.169486 |   0.406448 |
|   32 |  0.875871 |   0.242876 |    0.85543 |
|   64 |  1.583077 |   0.465915 |   1.506953 |
|  128 |  3.198071 |   0.903894 |    3.09165 |
|  256 |  6.786677 |   2.149489 |   6.779569 |
|  512 | 17.346131 |    8.92149 |  17.971033 |
| 1024 | 63.358453 |  46.152089 |  65.401559 |
+------+-----------+------------+------------+

(In the tables 'Completion' is time until completion answers after a
top-level change and 'Fully done' is time until the analyzer stops
analyzing after a top-level change).

Change-Id: Id7214c0d6c14199f39c0c8a6a8b4941a0e575dc3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/413401
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
2025-03-06 23:43:58 -08:00

50 lines
1.6 KiB
Dart

// Copyright (c) 2019, 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 'dart:io' show Directory, File, Platform, Process, ProcessResult;
import 'package:_fe_analyzer_shared/src/util/filenames.dart';
// This file is a copy of pkg/front_end/test/utils/io_utils.dart
String computeRepoDir() {
Uri uri;
if (Platform.script.hasAbsolutePath) {
uri = Platform.script;
} else if (Platform.packageConfig != null) {
String packageConfig = Platform.packageConfig!;
String prefix = 'file://';
if (packageConfig.startsWith(prefix)) {
uri = Uri.parse(packageConfig);
} else {
uri = Uri.base.resolve(nativeToUriPath(packageConfig));
}
} else {
throw "Can't obtain the path to the SDK either via "
'Platform.script or Platform.packageConfig';
}
String path = File.fromUri(uri).parent.path;
ProcessResult result = Process.runSync(
'git',
['rev-parse', '--show-toplevel'],
runInShell: true,
workingDirectory: path,
);
if (result.exitCode != 0) {
throw 'Git returned non-zero error code (${result.exitCode}):\n\n'
'stdout: ${result.stdout}\n\n'
'stderr: ${result.stderr}';
}
String dirPath = (result.stdout as String).trim();
if (!Directory(dirPath).existsSync()) {
throw 'The path returned by git ($dirPath) does not actually exist.';
}
return dirPath;
}
Uri computeRepoDirUri() {
String dirPath = computeRepoDir();
return Directory(dirPath).uri;
}