ff87171f6c
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>
151 lines
3.8 KiB
Dart
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();
|
|
}
|
|
}
|