| // Copyright (c) 2021, 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'; | 
 | import 'dart:math'; | 
 |  | 
 | import 'package:expect/expect.dart'; | 
 |  | 
 | // Implements recursive summation via tail calls: | 
 | //   fib(n) => n <= 1 ? 1 | 
 | //                    : fib(n-1) + fib(n-2); | 
 | Future fibonacciRecursive(List args) async { | 
 |   final SendPort port = args[0]; | 
 |   final n = args[1]; | 
 |   if (n <= 1) { | 
 |     port.send(1); | 
 |     return; | 
 |   } | 
 |   final left = ReceivePort(); | 
 |   final right = ReceivePort(); | 
 |   await Future.wait([ | 
 |     Isolate.spawn(fibonacciRecursive, [left.sendPort, n - 1]), | 
 |     Isolate.spawn(fibonacciRecursive, [right.sendPort, n - 2]), | 
 |   ]); | 
 |   final results = await Future.wait([left.first, right.first]); | 
 |   port.send(results[0] + results[1]); | 
 | } | 
 |  | 
 | Future<void> main() async { | 
 |   final rpWarmup = ReceivePort(); | 
 |   final rpRun = ReceivePort(); | 
 |   final int nWarmup = 17; // enough runs to trigger optimized compilation | 
 |   final int nWarmupFactorial = 2584; | 
 |   // Runs for about 8 seconds. | 
 |   final int n = 21; | 
 |   final int nFactorial = 17711; | 
 |   final beforeRss = ProcessInfo.currentRss; | 
 |  | 
 |   int maxRss = beforeRss; | 
 |   final rssTimer = Timer.periodic(const Duration(milliseconds: 10), (_) { | 
 |     maxRss = max(ProcessInfo.currentRss, maxRss); | 
 |   }); | 
 |  | 
 |   final watch = Stopwatch(); | 
 |   watch.start(); | 
 |  | 
 |   // Warm up code by running a couple iterations in the main isolate. | 
 |   await Isolate.spawn(fibonacciRecursive, [rpWarmup.sendPort, nWarmup]); | 
 |   Expect.equals(nWarmupFactorial, await rpWarmup.first); | 
 |  | 
 |   final warmup = watch.elapsedMicroseconds; | 
 |  | 
 |   await Isolate.spawn(fibonacciRecursive, [rpRun.sendPort, n]); | 
 |   Expect.equals(nFactorial, await rpRun.first); | 
 |  | 
 |   final done = watch.elapsedMicroseconds; | 
 |  | 
 |   print('IsolateFibonacci_$n.Calculation(RunTimeRaw): ${done - warmup} us.'); | 
 |   print('IsolateFibonacci_$n.DeltaPeak(MemoryUse): ${maxRss - beforeRss}'); | 
 |   rssTimer.cancel(); | 
 | } |