| // Copyright (c) 2024, 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. | |
| import 'dart:convert'; | |
| import 'dart:js_interop'; | |
| import 'dart:typed_data'; | |
| import 'package:benchmark_harness/benchmark_harness.dart'; | |
| void main(List<String> args) { | |
| final smallDartString = 'a' * 10; | |
| final mediumDartString = 'a' * 1024; | |
| final largeDartString = 'a' * 1024 * 1024; | |
| final smallJsString = smallDartString.toJS; | |
| final mediumJsString = mediumDartString.toJS; | |
| final largeJsString = largeDartString.toJS; | |
| final smallDartBytes = utf8.encode(smallDartString); | |
| final mediumDartBytes = utf8.encode(mediumDartString); | |
| final largeDartBytes = utf8.encode(largeDartString); | |
| final smallJsBytes = smallDartBytes.toJS; | |
| final mediumJsBytes = mediumDartBytes.toJS; | |
| final largeJsBytes = largeDartBytes.toJS; | |
| WasmDataTransferFromBrowserString(smallJsString, '10').report(); | |
| WasmDataTransferFromBrowserBytes(smallJsBytes, '10').report(); | |
| WasmDataTransferToBrowserString(smallDartString, '10').report(); | |
| WasmDataTransferToBrowserBytes(smallDartBytes, '10').report(); | |
| WasmDataTransferFromBrowserString(mediumJsString, '1KB').report(); | |
| WasmDataTransferFromBrowserBytes(mediumJsBytes, '1KB').report(); | |
| WasmDataTransferToBrowserString(mediumDartString, '1KB').report(); | |
| WasmDataTransferToBrowserBytes(mediumDartBytes, '1KB').report(); | |
| WasmDataTransferFromBrowserString(largeJsString, '1MB').report(); | |
| WasmDataTransferFromBrowserBytes(largeJsBytes, '1MB').report(); | |
| WasmDataTransferToBrowserString(largeDartString, '1MB').report(); | |
| WasmDataTransferToBrowserBytes(largeDartBytes, '1MB').report(); | |
| } | |
| class PrintEmitter implements ScoreEmitter { | |
| const PrintEmitter(); | |
| @override | |
| void emit(String testName, double value) { | |
| print('$testName(RunTimeRaw): $value us.'); | |
| } | |
| } | |
| abstract class Benchmark extends BenchmarkBase { | |
| Benchmark(super.name) : super(emitter: const PrintEmitter()); | |
| @override | |
| void exercise() { | |
| // To avoid using the super class's implementation which runs for 10 | |
| // iterations thereby making the measured time off by 10x. | |
| run(); | |
| } | |
| } | |
| class WasmDataTransferFromBrowserString extends Benchmark { | |
| final JSString jsonString; | |
| WasmDataTransferFromBrowserString(this.jsonString, String subName) | |
| : super('WasmDataTransfer.FromBrowserString.$subName'); | |
| @override | |
| void run() { | |
| // We don't expose a way to convert JS string to Dart string (as string | |
| // implementation in Dart is implementation specific - we may even use JS | |
| // strings). | |
| // | |
| // But currently we use internal one/two byte strings and using string | |
| // interpolation forces transfer of string to be internal string. | |
| // | |
| // Though string interpolation also causes other work (it converts JS string | |
| // to dart and then allocates new string for interpolation result) | |
| use('a${jsonString.toDart}'); | |
| } | |
| } | |
| class WasmDataTransferFromBrowserBytes extends Benchmark { | |
| final JSUint8Array bytes; | |
| WasmDataTransferFromBrowserBytes(this.bytes, String subName) | |
| : super('WasmDataTransfer.FromBrowserBytes.$subName'); | |
| @override | |
| void run() { | |
| use(Uint8List.fromList(bytes.toDart)); | |
| } | |
| } | |
| class WasmDataTransferToBrowserString extends Benchmark { | |
| final String string; | |
| WasmDataTransferToBrowserString(this.string, String subName) | |
| : super('WasmDataTransfer.ToBrowserString.$subName'); | |
| @override | |
| void run() { | |
| use(string.toJS); | |
| } | |
| } | |
| class WasmDataTransferToBrowserBytes extends Benchmark { | |
| final Uint8List bytes; | |
| WasmDataTransferToBrowserBytes(this.bytes, String subName) | |
| : super('WasmDataTransfer.ToBrowserBytes.$subName'); | |
| @override | |
| void run() { | |
| use(bytes.toJS); | |
| } | |
| } | |
| var globalSink; | |
| void use<T>(T a) { | |
| globalSink = a; | |
| if (kFalse) print(globalSink); | |
| } | |
| final kTrue = int.parse('1') == 1; | |
| final kFalse = !kTrue; |