我正在学习DART的isolate,阅读the official tutorial.然而,我不明白孤立比async有什么优势.

为了了解隔离是如何工作的,我编写了以下简单的代码:

import 'dart:isolate';
import 'dart:math';

//generates many random numbers and returns the final result
Future<int> f({required int seed}) async {
  const numIter = 100000000;
  const upperBound = 10000;

  var r = Random(seed);
  for (var i = 0; i < numIter; ++i) {
    r.nextInt(upperBound); //just discards the result
  }
  return r.nextInt(upperBound);
}

void main() async {
  var sw = Stopwatch();
  sw.start();

  final future1 = f(seed: 0);
  // final future2 = Isolate.run(() async => f(seed: 1));
  // final future2 = f(seed: 1);
  print(await future1);
  // print(await future2);

  sw.stop();
  print(sw.elapsedMilliseconds.toString() + "(ms)");
}

输出是685(ms).

如果我取消这两行的注释,

// final future2 = f(seed: 1);
// print(await future2);

输出变为1338(ms),大约是之前的685(ms)的两倍.由于DART是单线程的(默认情况下只有main isolate),因此这是意料之中的.到目前一切尚好.

然后,如果我取消这两行的注释,

// final future2 = Isolate.run(() async => f(seed: 1));
// print(await future2);

输出变为1304(ms).为什么?我预计输出将保持在600(ms)左右,因为Isolate.run()引入了另一个执行线程.

Environment:台M1 Macbook.代码通过dart run命令运行.

推荐答案

@jamesdlin是正确的.因为f()实际上不是异步的,所以语句final future1 = f(seed: 0);在创建第二个隔离之前阻止主隔离.

您可以使用以下命令查看此内容:

import 'dart:isolate';
import 'dart:math';

//generates many random numbers and returns the final result
Future<int> f({required int seed}) async {
  const numIter = 100000000;
  const upperBound = 10000;

  var r = Random(seed);
  for (var i = 0; i < numIter; ++i) {
    r.nextInt(upperBound); //just discards the result
  }
  return r.nextInt(upperBound);
}

void main() async {
  var sw = Stopwatch();
  sw.start();

  final future1 = f(seed: 0);
  print(sw.elapsedMilliseconds.toString() + "(ms)");
  final future2 = Isolate.run(() async => f(seed: 1));
  print(await future1);
  print(await future2);

  sw.stop();
  print(sw.elapsedMilliseconds.toString() + "(ms)");
}

以下哪项输出:

962(ms)
1124
4512
1946(ms)

下面的修改将更符合您的预期:

import 'dart:isolate';
import 'dart:math';

//generates many random numbers and returns the final result
int f({required int seed}) {
  const numIter = 1000000000;
  const upperBound = 10000;

  var r = Random(seed);
  for (var i = 0; i < numIter; ++i) {
    r.nextInt(upperBound); //just discards the result
  }
  return r.nextInt(upperBound);
}

void main() async {
  var sw = Stopwatch();
  sw.start();

  final future1 = Isolate.run(() => f(seed: 0));
  final future2 = Isolate.run(() => f(seed: 1));
  print(await future1);
  print(await future2);

  sw.stop();
  print(sw.elapsedMilliseconds.toString() + "(ms)");
}

Dart相关问答推荐

将 Stream> 转换为 Stream

如何在flutter中管理switch小部件的原生外观

Flutter - 删除元素时 UI 未正确更新

在启用 null 安全性的情况下,如何在 Iterable.firstWhere 中从 orElse 返回 null?

默认情况下不可为空(Non-nullable ):如何启用experiment?

如何使用Flutter在按钮网格中滑动(swipe)/拖动(drag) 2 个或更多按钮

如何用 Flutter 在同屏路由上制作英雄风格的动画?

如何通过 foreach 函数避免在 dart Map 中使用 await 键

Dart VM 的性能与 Node.js 相比如何?

Dart:Streams与 ValueNotifiers

如何在组件类中获取 ngForm 变量引用?

如何创建一个对话框,能够接受文本输入并在Flutter中显示结果?

找不到正确的提供程序-Flutter

如何创建带有固定页脚和Flutter的滚动视图?

如何在 Visual Studio Code 中禁用fake右括号注释?

如何在dart列表中找到一个元素

从 Dart 应用访问 pubspec.yaml 属性

GWT 与 Dart - 主要区别是什么? Dart 是 GWT 的潜在替代品吗?

如何在 Dart 中连接两个字符串?

如何从 Dart 中的列表中获取随机元素?