Files
sdk/benchmarks/Isolate/dart/Isolate.dart
T
Jonas Termansen 630302b710 Roll benchmark_harness and use AsyncBenchmarkBase.
Change-Id: I9089b566082d06cb4947e9720cbafedccc901a60
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/242872
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Alexander Thomas <athom@google.com>
Commit-Queue: Jonas Termansen <sortie@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2022-05-02 09:27:49 +00:00

145 lines
3.8 KiB
Dart

// Copyright (c) 2019, 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:async';
import 'dart:isolate';
import 'dart:typed_data';
import 'package:benchmark_harness/benchmark_harness.dart';
class SendReceiveBytes extends AsyncBenchmarkBase {
SendReceiveBytes(String name,
{required this.size, required this.useTransferable})
: super(name);
@override
Future<void> run() async {
await helper.run();
}
@override
Future<void> setup() async {
helper = SendReceiveHelper(size, useTransferable: useTransferable);
await helper.setup();
}
@override
Future<void> teardown() async {
await helper.finalize();
}
final bool useTransferable;
final int size;
late SendReceiveHelper helper;
}
class StartMessage {
final SendPort sendPort;
final bool useTransferable;
final int size;
StartMessage(this.sendPort, this.useTransferable, this.size);
}
// Measures how long sending and receiving of [size]-length Uint8List takes.
class SendReceiveHelper {
SendReceiveHelper(this.size, {required this.useTransferable});
Future<void> setup() async {
data = Uint8List(size);
port = ReceivePort();
inbox = StreamIterator<dynamic>(port);
workerCompleted = Completer<bool>();
workerExitedPort = ReceivePort()
..listen((_) => workerCompleted.complete(true));
worker = await Isolate.spawn(
isolate, StartMessage(port.sendPort, useTransferable, size),
onExit: workerExitedPort.sendPort);
await inbox.moveNext();
outbox = inbox.current;
}
Future<void> finalize() async {
outbox.send(null);
await workerCompleted.future;
workerExitedPort.close();
port.close();
}
// Send data to worker, wait for an answer.
Future<void> run() async {
outbox.send(packageList(data, useTransferable));
await inbox.moveNext();
final received = inbox.current;
if (useTransferable) {
final TransferableTypedData transferable = received;
transferable.materialize();
}
}
late Uint8List data;
late ReceivePort port;
late StreamIterator<dynamic> inbox;
late SendPort outbox;
late Isolate worker;
late Completer<bool> workerCompleted;
late ReceivePort workerExitedPort;
final int size;
final bool useTransferable;
}
Object packageList(Uint8List data, bool useTransferable) =>
useTransferable ? TransferableTypedData.fromList(<Uint8List>[data]) : data;
Future<void> isolate(StartMessage startMessage) async {
final port = ReceivePort();
final inbox = StreamIterator<dynamic>(port);
final data = Uint8List.view(Uint8List(startMessage.size).buffer);
startMessage.sendPort.send(port.sendPort);
while (true) {
await inbox.moveNext();
final received = inbox.current;
if (received == null) {
break;
}
if (startMessage.useTransferable) {
final TransferableTypedData transferable = received;
transferable.materialize();
}
startMessage.sendPort.send(packageList(data, startMessage.useTransferable));
}
port.close();
}
class SizeName {
const SizeName(this.size, this.name);
final int size;
final String name;
}
const List<SizeName> sizes = <SizeName>[
SizeName(1 * 1024, '1KB'),
SizeName(10 * 1024, '10KB'),
SizeName(100 * 1024, '100KB'),
SizeName(1 * 1024 * 1024, '1MB'),
SizeName(10 * 1024 * 1024, '10MB'),
SizeName(100 * 1024 * 1024, '100MB')
];
Future<void> main() async {
for (final sizeName in sizes) {
await SendReceiveBytes('Isolate.SendReceiveBytes${sizeName.name}',
size: sizeName.size, useTransferable: false)
.report();
await SendReceiveBytes(
'Isolate.SendReceiveBytesTransferable${sizeName.name}',
size: sizeName.size,
useTransferable: true)
.report();
}
}