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