|  | // 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; | 
|  | } |