|  | // 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:js_interop'; | 
|  | import 'dart:convert'; | 
|  | 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 convers 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; |