|  | // 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 | 
|  |  | 
|  | 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<String> benchmarkTextChunks = List.empty(growable: true); | 
|  |  | 
|  | 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<int> runes = repeatedText.runes.toList(); | 
|  | final int nChunks = (size < nRunes) ? (nRunes / size).floor() : 1; | 
|  | for (int i = 0; i < nChunks; i++) { | 
|  | final offset = i * size; | 
|  | benchmarkTextChunks.add( | 
|  | 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<String> 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(); | 
|  | } | 
|  | } |