Skip to content

Commit 3e2ee13

Browse files
authored
[benchmark_harness] require Dart 3.10, format code, prepare release (#2256)
1 parent fe1a6e0 commit 3e2ee13

File tree

13 files changed

+145
-95
lines changed

13 files changed

+145
-95
lines changed

.github/workflows/benchmark_harness.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ jobs:
5555
matrix:
5656
# Add macos-latest and/or windows-latest if relevant for this package.
5757
os: [ubuntu-latest]
58-
sdk: [3.2, dev]
58+
# Have to put `'3.10'` instead of `3.10` because of
59+
# https://github.com/dart-lang/setup-dart/issues/161
60+
sdk: ['3.10', dev]
5961
steps:
6062
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
6163
- uses: dart-lang/setup-dart@e51d8e571e22473a2ddebf0ef8a2123f0ab2c02c

pkgs/benchmark_harness/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
## 2.4.0-wip
1+
## 2.4.0
22

33
- Added a `bench` command.
4+
- Require `sdk: ^3.10.0`.
45

56
## 2.3.1
67

pkgs/benchmark_harness/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,26 +42,26 @@ In other words, don't compare apples with oranges.
4242

4343
## Getting Started
4444

45-
1\. Add the following to your project's **pubspec.yaml**
45+
1. Add the following to your project's **pubspec.yaml**
4646

4747
```yaml
4848
dependencies:
4949
benchmark_harness: any
5050
```
5151
52-
2\. Install pub packages
52+
2. Install pub packages
5353
5454
```sh
5555
dart pub install
5656
```
5757

58-
3\. Add the following import:
58+
3. Add the following import:
5959

6060
```dart
6161
import 'package:benchmark_harness/benchmark_harness.dart';
6262
```
6363

64-
4\. Create a benchmark class which inherits from `BenchmarkBase` or
64+
4. Create a benchmark class which inherits from `BenchmarkBase` or
6565
`AsyncBenchmarkBase`.
6666

6767
## Example
@@ -113,7 +113,7 @@ Template(RunTime): 0.1568472448997197 us.
113113

114114
This is the average amount of time it takes to run `run()` 10 times for
115115
`BenchmarkBase` and once for `AsyncBenchmarkBase`.
116-
> µs is an abbreviation for microseconds.
116+
> `us` is an abbreviation for microseconds.
117117
118118
## `bench` command
119119

pkgs/benchmark_harness/analysis_options.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# https://dart.dev/guides/language/analysis-options
2+
13
include: package:dart_flutter_team_lints/analysis_options.yaml
24

35
analyzer:

pkgs/benchmark_harness/lib/src/async_benchmark_base.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ class AsyncBenchmarkBase {
3636
/// Measures the score for this benchmark by executing it repeatedly until
3737
/// time minimum has been reached.
3838
static Future<double> measureFor(
39-
Future<void> Function() f, int minimumMillis) async {
39+
Future<void> Function() f,
40+
int minimumMillis,
41+
) async {
4042
final minimumMicros = minimumMillis * 1000;
4143
final watch = Stopwatch()..start();
4244
var iter = 0;

pkgs/benchmark_harness/lib/src/bench_command/bench_options.dart

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import 'package:args/args.dart';
77
enum RuntimeFlavor {
88
aot(help: 'Compile and run as a native binary.'),
99
jit(
10-
help: 'Run as-is without compilation, '
10+
help:
11+
'Run as-is without compilation, '
1112
'using the just-in-time (JIT) runtime.',
1213
),
1314
js(help: 'Compile to JavaScript and run on node.'),
@@ -36,13 +37,17 @@ class BenchOptions {
3637
final result = _parserForBenchOptions.parse(args);
3738

3839
if (result.rest.isNotEmpty) {
39-
throw FormatException('All arguments must be provided via `--` options. '
40-
'Not sure what to do with "${result.rest.join()}".');
40+
throw FormatException(
41+
'All arguments must be provided via `--` options. '
42+
'Not sure what to do with "${result.rest.join()}".',
43+
);
4144
}
4245

4346
return BenchOptions(
44-
flavor:
45-
result.multiOption('flavor').map(RuntimeFlavor.values.byName).toSet(),
47+
flavor: result
48+
.multiOption('flavor')
49+
.map(RuntimeFlavor.values.byName)
50+
.toSet(),
4651
target: result.option('target')!,
4752
help: result.flag('help'),
4853
verbose: result.flag('verbose'),
@@ -60,23 +65,31 @@ class BenchOptions {
6065
static String get usage => _parserForBenchOptions.usage;
6166

6267
static final _parserForBenchOptions = ArgParser()
63-
..addMultiOption('flavor',
64-
abbr: 'f',
65-
allowed: RuntimeFlavor.values.map((e) => e.name),
66-
allowedHelp: {
67-
for (final flavor in RuntimeFlavor.values) flavor.name: flavor.help
68-
})
69-
..addOption('target',
70-
defaultsTo: 'benchmark/benchmark.dart',
71-
help: 'The target script to compile and run.')
72-
..addFlag('help',
73-
defaultsTo: false,
74-
negatable: false,
75-
help: 'Print usage information and quit.',
76-
abbr: 'h')
77-
..addFlag('verbose',
78-
defaultsTo: false,
79-
negatable: false,
80-
help: 'Print the full stack trace if an exception is thrown.',
81-
abbr: 'v');
68+
..addMultiOption(
69+
'flavor',
70+
abbr: 'f',
71+
allowed: RuntimeFlavor.values.map((e) => e.name),
72+
allowedHelp: {
73+
for (final flavor in RuntimeFlavor.values) flavor.name: flavor.help,
74+
},
75+
)
76+
..addOption(
77+
'target',
78+
defaultsTo: 'benchmark/benchmark.dart',
79+
help: 'The target script to compile and run.',
80+
)
81+
..addFlag(
82+
'help',
83+
defaultsTo: false,
84+
negatable: false,
85+
help: 'Print usage information and quit.',
86+
abbr: 'h',
87+
)
88+
..addFlag(
89+
'verbose',
90+
defaultsTo: false,
91+
negatable: false,
92+
help: 'Print the full stack trace if an exception is thrown.',
93+
abbr: 'v',
94+
);
8295
}

pkgs/benchmark_harness/lib/src/bench_command/compile_and_run.dart

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ enum _Stage { compile, run }
3939
/// Base class for runtime-specific runners.
4040
abstract class _Runner {
4141
_Runner._({required this.target, required this.flavor})
42-
: assert(FileSystemEntity.isFileSync(target), '$target is not a file');
42+
: assert(FileSystemEntity.isFileSync(target), '$target is not a file');
4343

4444
factory _Runner({required RuntimeFlavor flavor, required String target}) {
4545
return (switch (flavor) {
@@ -58,8 +58,9 @@ abstract class _Runner {
5858
///
5959
/// Takes care of creating and deleting the corresponding temp directory.
6060
Future<void> run() async {
61-
_tempDirectory = Directory.systemTemp
62-
.createTempSync('bench_${DateTime.now().millisecondsSinceEpoch}_');
61+
_tempDirectory = Directory.systemTemp.createTempSync(
62+
'bench_${DateTime.now().millisecondsSinceEpoch}_',
63+
);
6364
try {
6465
await _runImpl();
6566
} finally {
@@ -75,14 +76,20 @@ abstract class _Runner {
7576
/// Also prints out a nice message before execution denoting the [flavor] and
7677
/// the [stage].
7778
Future<void> _runProc(
78-
_Stage stage, String executable, List<String> args) async {
79+
_Stage stage,
80+
String executable,
81+
List<String> args,
82+
) async {
7983
print('''
8084
\n${flavor.name.toUpperCase()} - ${stage.name.toUpperCase()}
8185
$executable ${args.join(' ')}
8286
''');
8387

84-
final proc = await Process.start(executable, args,
85-
mode: ProcessStartMode.inheritStdio);
88+
final proc = await Process.start(
89+
executable,
90+
args,
91+
mode: ProcessStartMode.inheritStdio,
92+
);
8693

8794
final exitCode = await proc.exitCode;
8895

@@ -156,14 +163,16 @@ class _WasmRunner extends _Runner {
156163
outFile,
157164
]);
158165

159-
final jsFile =
160-
File.fromUri(_tempDirectory.uri.resolve('$_outputFileRoot.js'));
166+
final jsFile = File.fromUri(
167+
_tempDirectory.uri.resolve('$_outputFileRoot.js'),
168+
);
161169
jsFile.writeAsStringSync(_wasmInvokeScript);
162170

163171
await _runProc(_Stage.run, 'node', [jsFile.path]);
164172
}
165173

166-
static const _wasmInvokeScript = '''
174+
static const _wasmInvokeScript =
175+
'''
167176
import { readFile } from 'node:fs/promises'; // For async file reading
168177
import { fileURLToPath } from 'url';
169178
import { dirname, join } from 'path';

pkgs/benchmark_harness/lib/src/measurement.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ Measurement measureForImpl(void Function() f, int minimumMillis) {
1212
final minimumMicros = minimumMillis * 1000;
1313
// If running a long measurement permit some amount of measurement jitter
1414
// to avoid discarding results that are almost good, but not quite there.
15-
final allowedJitter =
16-
minimumMillis < 1000 ? 0 : (minimumMicros * 0.1).floor();
15+
final allowedJitter = minimumMillis < 1000
16+
? 0
17+
: (minimumMicros * 0.1).floor();
1718
var iter = 2;
1819
var totalIterations = iter;
1920
final watch = Stopwatch()..start();
@@ -29,7 +30,8 @@ Measurement measureForImpl(void Function() f, int minimumMillis) {
2930
}
3031

3132
iter = measurement.estimateIterationsNeededToReach(
32-
minimumMicros: minimumMicros);
33+
minimumMicros: minimumMicros,
34+
);
3335
totalIterations += iter;
3436
}
3537
}

pkgs/benchmark_harness/lib/src/perf_benchmark_base.dart

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ class PerfBenchmarkBase extends BenchmarkBase {
1919
late final Process perfProcess;
2020
late final List<String> perfProcessArgs;
2121

22-
PerfBenchmarkBase(super.name,
23-
{ScoreEmitterV2 super.emitter = const PrintEmitterV2()});
22+
PerfBenchmarkBase(
23+
super.name, {
24+
ScoreEmitterV2 super.emitter = const PrintEmitterV2(),
25+
});
2426

2527
ScoreEmitterV2 get _emitterV2 => emitter as ScoreEmitterV2;
2628

@@ -30,8 +32,12 @@ class PerfBenchmarkBase extends BenchmarkBase {
3032
for (final path in [perfControlFifo, perfControlAck]) {
3133
final fifoResult = await Process.run('mkfifo', [path]);
3234
if (fifoResult.exitCode != 0) {
33-
throw ProcessException('mkfifo', [path],
34-
'Cannot create fifo: ${fifoResult.stderr}', fifoResult.exitCode);
35+
throw ProcessException(
36+
'mkfifo',
37+
[path],
38+
'Cannot create fifo: ${fifoResult.stderr}',
39+
fifoResult.exitCode,
40+
);
3541
}
3642
}
3743
}
@@ -70,27 +76,33 @@ class PerfBenchmarkBase extends BenchmarkBase {
7076
// Exit code from perf is -SIGINT when terminated with SIGINT.
7177
if (exitCode != 0 && exitCode != -ProcessSignal.sigint.signalNumber) {
7278
throw ProcessException(
73-
'perf', perfProcessArgs, lines.join('\n'), exitCode);
79+
'perf',
80+
perfProcessArgs,
81+
lines.join('\n'),
82+
exitCode,
83+
);
7484
}
7585

76-
const metrics = {
77-
'cycles': 'CpuCycles',
78-
'page-faults': 'MajorPageFaults',
79-
};
86+
const metrics = {'cycles': 'CpuCycles', 'page-faults': 'MajorPageFaults'};
8087
for (final line in lines) {
81-
if (line.split('\t')
82-
case [
83-
String counter,
84-
_,
85-
String event && ('cycles' || 'page-faults'),
86-
...
87-
]) {
88-
_emitterV2.emit(name, double.parse(counter) / totalIterations,
89-
metric: metrics[event]!);
88+
if (line.split('\t') case [
89+
String counter,
90+
_,
91+
String event && ('cycles' || 'page-faults'),
92+
...,
93+
]) {
94+
_emitterV2.emit(
95+
name,
96+
double.parse(counter) / totalIterations,
97+
metric: metrics[event]!,
98+
);
9099
}
91100
}
92-
_emitterV2.emit('$name.totalIterations', totalIterations.toDouble(),
93-
metric: 'Count');
101+
_emitterV2.emit(
102+
'$name.totalIterations',
103+
totalIterations.toDouble(),
104+
metric: 'Count',
105+
);
94106
}
95107

96108
/// Measures the score for the benchmark and returns it.

pkgs/benchmark_harness/lib/src/score_emitter.dart

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,12 @@ class PrintEmitter implements ScoreEmitter {
2020
/// be deprecated and removed. That release will be a breaking change.
2121
abstract class ScoreEmitterV2 implements ScoreEmitter {
2222
@override
23-
void emit(String testName, double value,
24-
{String metric = 'RunTime', String unit});
23+
void emit(
24+
String testName,
25+
double value, {
26+
String metric = 'RunTime',
27+
String unit,
28+
});
2529
}
2630

2731
/// New implementation of [PrintEmitter] implementing the [ScoreEmitterV2]
@@ -31,8 +35,12 @@ class PrintEmitterV2 implements ScoreEmitterV2 {
3135
const PrintEmitterV2();
3236

3337
@override
34-
void emit(String testName, double value,
35-
{String metric = 'RunTime', String unit = ''}) {
38+
void emit(
39+
String testName,
40+
double value, {
41+
String metric = 'RunTime',
42+
String unit = '',
43+
}) {
3644
print(['$testName($metric):', value, if (unit.isNotEmpty) unit].join(' '));
3745
}
3846
}

0 commit comments

Comments
 (0)