我是一名经验丰富的开发人员,但也是一名DART初学者.

我比较了返回Future.sync()的函数和不返回awaitasync函数,如下所示.

Future<void> measure(Future<int> Function() func) async {
  final watch = Stopwatch()..start();
  int sum = 0;
  for (int i = 0; i < 10000000; i++) {
    sum += await func();
  }
  print('sum:$sum, dt:${watch.elapsed}');
}

void main() async {
  int i = 0;
  await measure(() => Future<int>.sync(
    () {
      i++;
      return i * 2;
    }
  ));
  i = 0;
  await measure(
    () async {
      i++;
      return i * 2;
    }
  );
}

以下是结果.

sum:100000010000000, dt:0:00:00.747827
sum:100000010000000, dt:0:00:00.874562

它们是等同的吗?(我想是的)如果是,为什么后者比前者慢?我在哪里可以找到相关的文件?

推荐答案

Future.sync constructor运行其参数一次,捕获所有同步错误,然后返回结果作为将来的结果. 它基本上是相同的:

Future<T> futureSync<T>(FutureOr<T> Function() fun) {
  try {
    var result = fun();
    if (result is Future<T>) return result;
    return Future<T>.value(result);
  } catch (e, s) {
    return Future<T>.error(e, s);
  }
}

你的fun()实际上是=> ++i * 2;. (如果判断包含在DartDoc页面中的实际实现,这基本上就是它所做的,只是通过一些更多的错误处理,让Zones在同步错误变成异步错误之前将其截获.)

在您的例子中,这意味着它执行i++,然后返回一个新的Future<int>.value(i * 2);

没有awaitasync function同步运行代码,直到它返回或出错退出.如果回归是有future 的,那么这个future 是等待的.(你的future 不是future ). 它基本上是一样的:

Future<T> asyncFunc<T>(FutureOr<T> Function() body) {
  Completer<T> $c = Completer<T>();
  try {
    var result = fun();
    // Async return:
    if (result is Future<T>) {
      result.then<void>($c.complete, onError: $c.completeError);
    } else {
      $c.complete(result);
    }
  } catch (e, s) {
    $c.completeError(e, s);
  }
  return $c.future;
}

在您的例子中,在做i++之后,结果只是int,所以它总是取else的分支.这意味着它返回$c.future,而它已经完成了i * 2.

这两种方法的结果值应该没有差别,都返回了值为++i * 2Future<int>. 如果您的代码返回一个future 或抛出一个错误(至少如果所有编译器都正确地实现了async返回future ),它仍然是一样的.

唯一可能的区别将是时机. 您不应该依赖于异步代码的特定计时. (您不应该假设在一个平台上更快的方法在另一个平台上也一定更快.)

很可能async版本会在某个地方执行一个额外的延迟.或者稍晚一点.或者运行更多的代码来说明async条返回语句是相当复杂的. 这里的差别很小,我绝对不会因为性能原因而改变我所做的事情.除非我已经确定这个特殊的行动是一个瓶颈.

Dart相关问答推荐

Dart中使用set表达式的switch语句

如何在 Flutter 的 firebase_database 中执行事务?

angular.dart NgTwoWay 和 NgAttr 已弃用?

Flutter pod 安装问题 - # 的未定义方法 `each_child'

在 Dart 中定义一个接受参数的 getter

Flatter中的Sqlite,数据库assets如何工作

Flutter 扩展方法不起作用,它说undefined class和requires the extension-methods language feature

Flutter-创建一个倒计时(countdown)小部件

在dart中使用动态(可变)字符串作为正则表达式模式

如何在 Dart 中监听自定义事件?

Dart:默认 gitignore?

如何正确管理 Flutter 应用中的全局 textScaleFactor?

Dart null 安全性不适用于类字段

如何判断switch/case中对象的类型?

Dart - 如何在每次测试之后或之前运行函数?

Dart 中的异步可迭代映射

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

Angular.js 和 Angular.dart 的区别?

如何在 Dart 中定义接口?

Dart 会支持使用现有的 JavaScript 库吗?