mirror of
https://github.com/dart-lang/sdk
synced 2024-10-03 00:45:16 +00:00
b6aa2976dc
The benchmarks were using a range of antipatterns that did not do what the authors thought they did. It seems that the authors thought the warmup method has to run for a while and do the full warmup, but the truth is that the harness will do that for you by running the warmup function in a timed loop. Instead these patterns just wasted time by making the warmup more expensive and complex than needed. This change just removes the warmup overrides since none of them do anything positive. This change prepares us for future improvements to the benchmark harness. Fixes: b/324874055 Change-Id: Ib7c282123a2151614bc95a105a30e67221f11315 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/352022 Reviewed-by: William Hesse <whesse@google.com> Commit-Queue: Jonas Termansen <sortie@google.com>
137 lines
3.6 KiB
Dart
137 lines
3.6 KiB
Dart
// Copyright (c) 2020, 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.
|
|
//
|
|
// Benchmark for UTF-8 decoding
|
|
|
|
// @dart=2.9
|
|
|
|
import 'dart:convert';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:benchmark_harness/benchmark_harness.dart';
|
|
|
|
import 'datext_latin1_10k.dart';
|
|
import 'entext_ascii_10k.dart';
|
|
import 'netext_3_10k.dart';
|
|
import 'rutext_2_10k.dart';
|
|
import 'sktext_10k.dart';
|
|
import 'zhtext_10k.dart';
|
|
|
|
class Utf8Decode extends BenchmarkBase {
|
|
final String language;
|
|
final String text;
|
|
final int size;
|
|
final bool allowMalformed;
|
|
List<Uint8List> chunks;
|
|
int totalInputSize;
|
|
int totalOutputSize;
|
|
|
|
static String _makeName(String language, int size, bool allowMalformed) {
|
|
String name = 'Utf8Decode.$language.';
|
|
name += size >= 1000000
|
|
? '${size ~/ 1000000}M'
|
|
: size >= 1000
|
|
? '${size ~/ 1000}k'
|
|
: '$size';
|
|
if (allowMalformed) name += '.malformed';
|
|
return name;
|
|
}
|
|
|
|
Utf8Decode(this.language, this.text, this.size, this.allowMalformed)
|
|
: super(_makeName(language, size, allowMalformed));
|
|
|
|
@override
|
|
void setup() {
|
|
final Uint8List data = utf8.encode(text);
|
|
if (data.length != 10000) {
|
|
throw 'Expected input data of exactly 10000 bytes.';
|
|
}
|
|
if (size < data.length) {
|
|
// Split into chunks.
|
|
chunks = <Uint8List>[];
|
|
int startPos = 0;
|
|
for (int pos = size; pos < data.length; pos += size) {
|
|
int endPos = pos;
|
|
while ((data[endPos] & 0xc0) == 0x80) {
|
|
endPos--;
|
|
}
|
|
chunks.add(Uint8List.fromList(data.sublist(startPos, endPos)));
|
|
startPos = endPos;
|
|
}
|
|
chunks.add(Uint8List.fromList(data.sublist(startPos, data.length)));
|
|
totalInputSize = data.length;
|
|
totalOutputSize = text.length;
|
|
} else if (size > data.length) {
|
|
// Repeat data to the desired length.
|
|
final Uint8List expanded = Uint8List(size);
|
|
for (int i = 0; i < size; i++) {
|
|
expanded[i] = data[i % data.length];
|
|
}
|
|
chunks = <Uint8List>[expanded];
|
|
totalInputSize = size;
|
|
totalOutputSize = text.length * size ~/ data.length;
|
|
} else {
|
|
// Use data as is.
|
|
chunks = <Uint8List>[data];
|
|
totalInputSize = data.length;
|
|
totalOutputSize = text.length;
|
|
}
|
|
}
|
|
|
|
@override
|
|
void run() {
|
|
int lengthSum = 0;
|
|
for (int i = 0; i < chunks.length; i++) {
|
|
final String s = utf8.decode(chunks[i], allowMalformed: allowMalformed);
|
|
lengthSum += s.length;
|
|
}
|
|
if (lengthSum != totalOutputSize) {
|
|
throw 'Output length doesn\'t match expected.';
|
|
}
|
|
}
|
|
|
|
@override
|
|
void exercise() {
|
|
// Only a single run per measurement.
|
|
run();
|
|
}
|
|
|
|
@override
|
|
double measure() {
|
|
// Report time per input byte.
|
|
return super.measure() / totalInputSize;
|
|
}
|
|
|
|
@override
|
|
void report() {
|
|
// Report time in nanoseconds.
|
|
final double score = measure() * 1000.0;
|
|
print('$name(RunTime): $score ns.');
|
|
}
|
|
}
|
|
|
|
void main(List<String> args) {
|
|
const texts = {
|
|
'en': en,
|
|
'da': da,
|
|
'sk': sk,
|
|
'ru': ru,
|
|
'ne': ne,
|
|
'zh': zh,
|
|
};
|
|
final bool testMalformed =
|
|
args != null && args.isNotEmpty && args.first == 'malformed';
|
|
final benchmarks = [
|
|
// Only benchmark with allowMalformed: false unless specified otherwise.
|
|
for (bool allowMalformed in [false, if (testMalformed) true])
|
|
for (int size in [10, 10000, 10000000])
|
|
for (String language in texts.keys)
|
|
() => Utf8Decode(language, texts[language], size, allowMalformed)
|
|
];
|
|
|
|
for (var bm in benchmarks) {
|
|
bm().report();
|
|
}
|
|
}
|