mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 15:17:07 +00:00
4c20cedd30
Now that I'm able to open the entire SDK in VSC, I'm fixing some of the analysis issues in various files (carefully) without changing their meaning. In this case, I removed unnecessary imports from benchmarks. In regexp_benchmark I ignored one warning which likely would have changed the behavior of the code. BUG=https://github.com/dart-lang/sdk/issues/52419 Change-Id: I9a195a4e45121313bd9f065f2579a165c3fec05b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/303901 Auto-Submit: Eric Seidel <eric@shorebird.dev> Reviewed-by: William Hesse <whesse@google.com> Commit-Queue: William Hesse <whesse@google.com>
123 lines
4.1 KiB
Dart
123 lines
4.1 KiB
Dart
// Copyright (c) 2023, 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.
|
|
|
|
/// This benchmark compares a large switch statement on various kinds of
|
|
/// values. The switch statement is part of a finite-state-machine (FSM)
|
|
/// recognizer.
|
|
///
|
|
/// There are four copies of the same code, differing only by importing
|
|
/// different declarations of the type `State` which makes the same constant
|
|
/// names available using different types.
|
|
///
|
|
/// The switch dispatch on the following types is benchmarked:
|
|
///
|
|
/// - a compact range of `int` values,
|
|
/// - an enum,
|
|
/// - a class that is a bit like an `enum` but not declared as an enum,
|
|
/// - strings.
|
|
///
|
|
/// The actual state-machine is somewhat aritificial. It recognizes a character
|
|
/// string of '0' and '1' character 'bits' that encode a valid UTF-8 string. The
|
|
/// state machine has 48 states and minimal logic in most states, so that as
|
|
/// much time as possible is executing the switch dispatch.
|
|
///
|
|
/// The data is passed to the recogizer as a Uint8List to minimize the time to
|
|
/// access the bytes of the ASCII '0' / '1' character input sequence.
|
|
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:benchmark_harness/benchmark_harness.dart';
|
|
import 'package:expect/expect.dart';
|
|
|
|
import 'match_class.dart' as match_class;
|
|
import 'match_enum.dart' as match_enum;
|
|
import 'match_int.dart' as match_int;
|
|
import 'match_string.dart' as match_string;
|
|
|
|
class Benchmark extends BenchmarkBase {
|
|
final bool Function(Uint8List) match;
|
|
|
|
Benchmark(String kind, this.match) : super('SwitchFSM.$kind');
|
|
|
|
void validation() {
|
|
void check(String s, bool expected) {
|
|
Expect.equals(expected, match(convert(s)), '"$s"');
|
|
}
|
|
|
|
check('', true);
|
|
check('0', false);
|
|
check('00', false);
|
|
check('000', false);
|
|
check('0000', false);
|
|
check('00000', false);
|
|
check('000000', false);
|
|
check('0000000', false);
|
|
check('00000000', true);
|
|
check('01010101', true);
|
|
check('10000000', false);
|
|
check('001010101', false);
|
|
check('11000000' '00000000', false);
|
|
check('11000000' '10111111', true);
|
|
check('11000000' '11111111', false);
|
|
check('11100000' '00000000' '00000000', false);
|
|
check('11100000' '10000000' '00000000', false);
|
|
check('11100000' '10111111' '10111111', true);
|
|
check('11110111' '10111111' '10111111' '01111111', false);
|
|
check('11110111' '10111111' '10111111' '10111111', true);
|
|
Expect.equals(testInputLength, testInput.length);
|
|
}
|
|
|
|
static const testInputLength = 1000;
|
|
static final Uint8List testInput = convert(makeTestInput(testInputLength));
|
|
|
|
static String makeTestInput(int length) {
|
|
// The test input uses most states of the FSM. It is repeated and padded to
|
|
// make the length 1000.
|
|
final testPattern = ''
|
|
'11110111101111111011111110111111'
|
|
'111011111011111110111111'
|
|
'1101111110111111';
|
|
final paddingPattern = '00000000';
|
|
final repeats = testPattern * (length ~/ testPattern.length);
|
|
final padding =
|
|
paddingPattern * ((length - repeats.length) ~/ paddingPattern.length);
|
|
return repeats + padding;
|
|
}
|
|
|
|
static Uint8List convert(String s) => Uint8List.fromList(s.codeUnits);
|
|
|
|
@override
|
|
void run() {
|
|
Expect.equals(true, match(testInput));
|
|
}
|
|
}
|
|
|
|
enum SomeEnum { element }
|
|
|
|
void main() {
|
|
// TODO(http://dartbug.com/51657): dart2js will remove `_Enum.index` in simple
|
|
// programs that don't appear to use the field. This defeats the enum-switch
|
|
// optimization that works more reliably in larger programs. Remove this code
|
|
// that marks `_Enum.index` as used when #51657 is fixed.
|
|
Expect.equals(0, SomeEnum.element.index);
|
|
|
|
final benchmarks = [
|
|
Benchmark('enum', match_enum.match),
|
|
Benchmark('int', match_int.match),
|
|
Benchmark('class', match_class.match),
|
|
Benchmark('string', match_string.match),
|
|
];
|
|
|
|
for (final benchmark in benchmarks) {
|
|
benchmark.validation();
|
|
}
|
|
|
|
for (final benchmark in benchmarks) {
|
|
benchmark.warmup();
|
|
}
|
|
|
|
for (final benchmark in benchmarks) {
|
|
benchmark.report();
|
|
}
|
|
}
|