// Copyright (c) 2022, 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:io'; import 'dart:isolate'; const int count = 10000; // The benchmark will spawn a long chain of isolates, keeping all of them // alive until the last one which measures Rss at that point (i.e. when all // isolates are alive), thereby getting a good estimate of memory-overhead per // isolate. void main() async { final onDone = ReceivePort(); final lastIsolatePort = ReceivePort(); final startRss = ProcessInfo.currentRss; final startUs = DateTime.now().microsecondsSinceEpoch; await Isolate.spawn( worker, WorkerInfo(count, lastIsolatePort.sendPort), onExit: onDone.sendPort, ); final result = await lastIsolatePort.first as List; final lastIsolateRss = result[0] as int; final lastIsolateUs = result[1] as int; await onDone.first; final doneUs = DateTime.now().microsecondsSinceEpoch; final averageMemoryUsageInKB = (lastIsolateRss - startRss) / count / 1024; final averageStartLatencyInUs = (lastIsolateUs - startUs) / count; final averageFinishLatencyInUs = (doneUs - startUs) / count; print('IsolateBaseOverhead.Rss(MemoryUse): $averageMemoryUsageInKB'); print( 'IsolateBaseOverhead.StartLatency(Latency): $averageStartLatencyInUs us.', ); print( 'IsolateBaseOverhead.FinishLatency(Latency): $averageFinishLatencyInUs us.', ); } class WorkerInfo { final int id; final SendPort result; WorkerInfo(this.id, this.result); } Future worker(WorkerInfo workerInfo) async { if (workerInfo.id == 1) { workerInfo.result.send([ ProcessInfo.currentRss, DateTime.now().microsecondsSinceEpoch, ]); return; } final onExit = ReceivePort(); await Isolate.spawn( worker, WorkerInfo(workerInfo.id - 1, workerInfo.result), onExit: onExit.sendPort, ); await onExit.first; }