Skip to content
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

Using async/await as a general solution for handling with async code #166

Open
rterekhov opened this issue Jan 6, 2017 · 2 comments
Open
Milestone

Comments

@rterekhov
Copy link

We look with interest on using async/await as a general approach for working with futures in our project.
We did some tests on the library but found out that it produce much more java byte code then map/flatMap does in the same in the same situation (especially on scala 2.12).
So we wonder:
Is scala-async library ready for production?
Is it meant to be used as a general approach or should it be used careful just for complex async cases?
How much impact does it have on compilation time?
How much impact does it have on size of generated byte code?
Does it have any performance issues?

@retronym
Copy link
Member

retronym commented Jan 9, 2017

Is scala-async library ready for production?

Yes, I would say this is true. We work closely with one user that has deployed it widely.

Is it meant to be used as a general approach or should it be used careful just for complex async cases?

This is really a style issue that depends on your tastes. In general, some control flow patterns are easier to express with async, so there would be a stronger argument to use it for those ones. Some people prefer the consistent approach of also using async for cases where for comprehesions / flatMap would have similar readibility.

How much impact does it have on compilation time?

We don't have data on this, but it is an area that we're plan to investigate this year.

How much impact does it have on size of generated byte code?

async translate all the logic into a single class, rather than each continution into a separate function. In Scala 2.11, this typically reduces bytecode size. It also reduces runtime allocations of functions. In Scala 2.12, the bytecode for each of the functions is translated into a method, and the anon function class is created at link time with invokedynamic. Internally in the JVM, the representation is the same, but if you're just looking at the contents of JAR files, the function-based approach would appear more compact than in 2.11.

Does it have any performance issues?

One thing we're aware of is that for complex async blocks, we end up generating the code in one large method. This might exceed the threshold for the JVM to JIT compile, which could hurt performance. However, the cost of interpreting code might not be important compared to the cost of context switching in Future. Another improvement we're planning is to have a mode where the code for each state of the state machine is wrapped in a single private method, which would make things more JIT friendly.

We did some tests on the library but found out that it produce much more java byte code then map/flatMap does in the same in the same situation (especially on scala 2.12).

Could you share a self-contained example of this that we could discuss concretely?

@rterekhov
Copy link
Author

Thank you for the answers. It helps a lot.

@retronym retronym added this to the 1.0 milestone Jun 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants