// 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 encoding // @dart=2.9 import 'dart:convert'; 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 Utf8Encode extends BenchmarkBase { final String language; final String originalText; // Size is measured in number of runes rather than number of bytes. // This differs from the Utf8Decode benchmark, but runes are the input // to the encode function which makes them more natural than bytes here. final int size; List benchmarkTextChunks; static String _makeName(String language, int size) { String name = 'Utf8Encode.$language.'; name += size >= 1000000 ? '${size ~/ 1000000}M' : size >= 1000 ? '${size ~/ 1000}k' : '$size'; return name; } Utf8Encode(this.language, this.originalText, this.size) : super(_makeName(language, size)); @override void setup() { final int nRunes = originalText.runes.toList().length; final String repeatedText = originalText * (size / nRunes).ceil(); final List runes = repeatedText.runes.toList(); final int nChunks = (size < nRunes) ? (nRunes / size).floor() : 1; benchmarkTextChunks = List.filled(nChunks, null); for (int i = 0; i < nChunks; i++) { final offset = i * size; benchmarkTextChunks[i] = String.fromCharCodes( runes.sublist(offset, offset + size), ); } } @override void run() { for (int i = 0; i < benchmarkTextChunks.length; i++) { final encoded = utf8.encode(benchmarkTextChunks[i]); if (encoded.length < benchmarkTextChunks[i].length) { throw 'There should be at least as many encoded bytes as runes'; } } } @override void exercise() { // Only a single run per measurement. run(); } @override double measure() { // Report time per input rune. return super.measure() / size / benchmarkTextChunks.length; } @override void report() { // Report time in nanoseconds. final double score = measure() * 1000.0; print('$name(RunTime): $score ns.'); } } void main(List args) { const texts = {'en': en, 'da': da, 'sk': sk, 'ru': ru, 'ne': ne, 'zh': zh}; final benchmarks = [ for (int size in [10, 10000, 10000000]) for (String language in texts.keys) () => Utf8Encode(language, texts[language], size), ]; for (var bm in benchmarks) { bm().report(); } }