6b3abe0a98
Issue b/177800357. TEST=existing test suite Change-Id: Id6b113932ab7014b8fa6c105845c5c490b60f5e8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/181320 Commit-Queue: Alexander Aprelev <aam@google.com> Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
131 lines
3.6 KiB
Dart
131 lines
3.6 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.
|
|
|
|
// VMOptions=--enable-isolate-groups --experimental-enable-isolate-groups-jit
|
|
// VMOptions=--no-enable-isolate-groups
|
|
|
|
// Test that validates that transferables are faster than regular typed data.
|
|
|
|
import 'dart:async';
|
|
import 'dart:isolate';
|
|
import 'dart:typed_data';
|
|
|
|
import "package:expect/expect.dart";
|
|
|
|
const int toIsolateSize = 100 * 1024 * 1024;
|
|
const int fromIsolateSize = 100 * 1024 * 1024;
|
|
|
|
const int nIterations = 5;
|
|
|
|
int iteration;
|
|
bool keepTimerRunning;
|
|
|
|
main() async {
|
|
keepTimerRunning = true;
|
|
|
|
print('--- standard');
|
|
iteration = nIterations;
|
|
final stopwatch = new Stopwatch()..start();
|
|
await runBatch(useTransferable: false);
|
|
final standard = stopwatch.elapsedMilliseconds;
|
|
|
|
print('--- transferable');
|
|
iteration = nIterations;
|
|
stopwatch.reset();
|
|
await runBatch(useTransferable: true);
|
|
final transferable = stopwatch.elapsedMilliseconds;
|
|
print(
|
|
'standard($standard ms)/transferable($transferable ms): ${standard / transferable}x');
|
|
keepTimerRunning = false;
|
|
}
|
|
|
|
packageList(Uint8List data, bool useTransferable) {
|
|
return useTransferable
|
|
? TransferableTypedData.fromList(<Uint8List>[data])
|
|
: data;
|
|
}
|
|
|
|
class StartMessage {
|
|
final SendPort sendPort;
|
|
final bool useTransferable;
|
|
|
|
StartMessage(this.sendPort, this.useTransferable);
|
|
}
|
|
|
|
runBatch({bool useTransferable}) async {
|
|
Timer.run(idleTimer);
|
|
final port = ReceivePort();
|
|
final inbox = StreamIterator<dynamic>(port);
|
|
final worker = await Isolate.spawn(
|
|
isolateMain, StartMessage(port.sendPort, useTransferable),
|
|
paused: true);
|
|
final workerCompleted = Completer<bool>();
|
|
final workerExitedPort = ReceivePort()
|
|
..listen((_) => workerCompleted.complete(true));
|
|
worker.addOnExitListener(workerExitedPort.sendPort);
|
|
worker.resume(worker.pauseCapability);
|
|
|
|
await inbox.moveNext();
|
|
final outbox = inbox.current;
|
|
final workWatch = new Stopwatch();
|
|
final data = new Uint8List(toIsolateSize);
|
|
|
|
while (iteration-- > 0) {
|
|
final packagedData = packageList(data, useTransferable);
|
|
workWatch.start();
|
|
outbox.send(packagedData);
|
|
await inbox.moveNext();
|
|
|
|
final received = inbox.current;
|
|
final receivedData = received is TransferableTypedData
|
|
? received.materialize().asUint8List()
|
|
: received;
|
|
|
|
int time = workWatch.elapsedMilliseconds;
|
|
print('${time}ms for round-trip');
|
|
workWatch.reset();
|
|
|
|
Expect.equals(data.length, receivedData.length);
|
|
}
|
|
outbox.send(null);
|
|
|
|
await workerCompleted.future;
|
|
workerExitedPort.close();
|
|
port.close();
|
|
}
|
|
|
|
Future<Null> isolateMain(StartMessage startMessage) async {
|
|
final port = new ReceivePort();
|
|
final inbox = new StreamIterator<dynamic>(port);
|
|
startMessage.sendPort.send(port.sendPort);
|
|
final data = Uint8List.view(new Uint8List(fromIsolateSize).buffer);
|
|
while (true) {
|
|
await inbox.moveNext();
|
|
final received = inbox.current;
|
|
if (received == null) {
|
|
break;
|
|
}
|
|
final receivedData =
|
|
received is TransferableTypedData ? received.materialize() : received;
|
|
|
|
final packagedData = packageList(data, startMessage.useTransferable);
|
|
|
|
startMessage.sendPort.send(packagedData);
|
|
}
|
|
port.close();
|
|
}
|
|
|
|
final Stopwatch idleWatch = new Stopwatch();
|
|
|
|
void idleTimer() {
|
|
idleWatch.stop();
|
|
final time = idleWatch.elapsedMilliseconds;
|
|
if (time > 5) print('${time}ms since last checkin');
|
|
idleWatch.reset();
|
|
idleWatch.start();
|
|
if (keepTimerRunning) {
|
|
Timer.run(idleTimer);
|
|
}
|
|
}
|