Skip to content

DartVM async*/await for are slow #38176

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
a14n opened this issue Sep 2, 2019 · 7 comments
Closed

DartVM async*/await for are slow #38176

a14n opened this issue Sep 2, 2019 · 7 comments

Comments

@a14n
Copy link
Contributor

a14n commented Sep 2, 2019

I wrote several versions of the same code:

// the initial version
Stream<int> f1(Stream<int> stream) async* {
  await for (final e in stream) {
    if (e.isEven) {
      continue;
    }
    yield e;
  }
}

// only with method on stream
Stream<int> f2(Stream<int> stream) => stream.where((e) => !e.isEven);

// with a stream controller
Stream<int> f3(Stream<int> stream) {
  final sc = StreamController<int>();
  stream.where((e) => !e.isEven).listen(sc.add, onDone: sc.close);
  return sc.stream;
}

// without await for
Stream<int> f4(Stream<int> stream) async* {
  yield* stream.where((e) => !e.isEven);
}

I tested those methods on a stream of 1_000_000 integers. The results are almost the same on every runs (DartVM 2.4.1 and 2.5.0-dev.2.1):

  • f1: 0:00:00.767951
  • f2: 0:00:00.246713
  • f3: 0:00:00.346697
  • f4: 0:00:00.405180

It looks like some improvment could be done here to have better performance with await for and async*

@a14n
Copy link
Contributor Author

a14n commented Sep 4, 2019

/cc @mraleph

@mraleph
Copy link
Member

mraleph commented Sep 4, 2019

Duplicate of #29189

@mraleph mraleph marked this as a duplicate of #29189 Sep 4, 2019
@mraleph mraleph closed this as completed Sep 4, 2019
@mraleph
Copy link
Member

mraleph commented Sep 4, 2019

Thank you for the report.

We are aware that there is a performance gap between async functions and hand written equivalents on microbenchmarks and we plan to eventually address some of it.

If you have an example of a real world code that is significantly impacted by this gap please let us know - it would help us to prioritise fixing this.

@a14n
Copy link
Contributor Author

a14n commented Sep 4, 2019

Thank for pointing me to #29189 I didn't manage to find it before reporting the issue.

If you have an example of a real world code that is significantly impacted by this gap please let us know - it would help us to prioritise fixing this.

Acutally I submitted this issue because I was performing a performance test on a real application and was triing to improve it. In a nutshell the application consume a gRPC streams of events, applies some filter/map on them and writes the result to other gRPC output streams. After some changes to avoid async*/await for the application now handles more events per second.

@mraleph
Copy link
Member

mraleph commented Sep 4, 2019

@a14n Do you have some more complete example which includes some gRPC / server code etc? That would be very helpful.

@mraleph
Copy link
Member

mraleph commented Sep 4, 2019

/cc @mkustermann for planning

@a14n
Copy link
Contributor Author

a14n commented Sep 4, 2019

It's really hard to extract a simple repro :-/
Even worse a simple repro with gRPC I started shows better performance with async* compared to stream.where :'(
I guess the perfs really depend on environment here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants