Files
sdk/benchmarks/Isolate/dart/Isolate.dart
Robert Nystrom ff87171f6c Reformat benchmarks/ with 3.8 style.
Change-Id: Ied900f7d85addabc586823139aa78b879be035ea
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/425182
Auto-Submit: Bob Nystrom <rnystrom@google.com>
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
2025-04-29 07:46:46 -07:00

151 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();
}
}