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

Implement async/await semantics more closely in coroutines #31

Closed
bergus opened this issue Jul 13, 2016 · 6 comments
Closed

Implement async/await semantics more closely in coroutines #31

bergus opened this issue Jul 13, 2016 · 6 comments

Comments

@bergus
Copy link
Contributor

bergus commented Jul 13, 2016

Looking more closely at the async/await proposal it seems that every yield should at least wait one tick. Currently, if it yields a value or settled promise then the next step is called synchronously (_runAction instead of _when). This could even lead to a stack overflow.
Can anyone confirm this?

@briancavalier
Copy link
Owner

Just to get this out in the open: In general, it hasn't ever been my intention for creed to match ES6 semantics exactly. My intention is for it to be highly performant, architecturally elegant (imho!), and compact, and to have a simple but useful API.

Yeah, stack overflow is possible, but hard to imagine in practice. The chance of writing a real coroutine that yields that many settled promises or values, with no async between, seems very unlikely! I've been using it in production code for over a year, and never seen a coroutine stack that is even remotely near overflowing. Tens of frames is the deepest I've ever seen ... not hundreds or thousands.

That said, we should at least see what happens to performance when switching to _when. I know I played around with it in the past, but the code has changed since then, and I've forgotten what the impact was.

@bergus
Copy link
Contributor Author

bergus commented Jul 13, 2016

I know that matching semantics or providing a polyfill is not the point of creed, I just think that we should avoid deviations where they are unnecessary and could lead to quirks in details, so I wanted to raise this point.

Apart from overflowing a stack, there might be differences if we have two coroutines running concurrently:

const example = coroutine(function* (x) {
    for (let i = 0; i < 10; i++)
        yield console.log(x, i);
});
example("a");
example("b");

In theory, they should be interleaved.

Yes, it would be nice to see a performance comparison, though I guess the impact on real-world code is minor as yield would only be used on actual promises in there.

@briancavalier
Copy link
Owner

I guess the impact on real-world code is minor as yield would only be used on actual promises in there

Yeah, that's my feeling. I don't think anyone would ever actually write code like that console.log loop. And if they did, I doubt they would care that it wasn't interleaved.

If there are cases where a reasonable usage might cause a problem, and if the performance checks out, it could be worth changing it. I'll try it with _when later tonight and post some results.

@briancavalier
Copy link
Owner

I'm running an unrelated experiment (for work) on my laptop tonight, so I don't really have any perf results that I'd call "reliable" :) But, I did try a bunch of runs of the doxbee perf test anyway just to see if there was any glaringly obvious difference. There wasn't, which is at least interesting enough to try it when my machine is idle, and to try the other perf tests as well. I'll try to post some representative results tomorrow.

bergus added a commit to bergus/creed that referenced this issue Jul 23, 2016
@bergus
Copy link
Contributor Author

bergus commented Jul 23, 2016

Given your benchmark in #20 I went forward with this.

@briancavalier
Copy link
Owner

Cool 👍

bergus added a commit to bergus/creed that referenced this issue Jul 29, 2016
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