-
Notifications
You must be signed in to change notification settings - Fork 21
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
Benchmarks? #11
Comments
This is a common scenario, and not one the async/await definition deals with well. The solution is a "PromiseCache", where the Promise holds any cached value (I've been meaning to generalise this case into a module). Obviously, you can expose the other Map methods by delegation, or change the signature to something less general where the function that fills the cache can be directly invoked within 'set' to avoid you having to pass it in. In my (many) implementations I often store the time the cache entry was set and evict them if they are old, or on a FIFO basis to stop the cache growing forever. Finally, all proper "Promises" actually resolve on the next tick, which is a significant overhead if you're repeatedly using the cached values. You can avoid this by using the To see the differences in action, go into nodent's installation (under node_modules for your project) and type
You'll see that nodent.Thenable is much faster in "Promise" mode than standard Promise implementations*, and that generators are pretty much useless for high performance. When it comes to standard Promise implementations, I find I hope that helps - if it does, please close the issue, otherwise feel free to get back to me. *If you're wondering how/why, it's that nodent's async/await implementation never generates code where multiple listeners await on the same result, and never generate chained Promises (they are nested), and so much of the internal logic of a Promise isn't needed. |
Found the nodent.Thenable version - basically an additional two lines. If you're doing a lot of sync retrieval, this is faster - although you should make sure it meets your use-cases fully.
|
Hey, This is pretty interesting stuff - I'm basically kind of doing that already - but the addition of the fast-async makes the difference as it no longer smashes the event loop. To avoid the same problem I'd also started basically creating something that looks 'Promise-like', so you can resolve static-values easily.
In short, I chain thenables ad-infinitum until I hit either 1000 of them or I hit a non-thenable, then just apply the wrapper again. I then just use Sync.resolve for code that's supposed to generate promises - but I'm wondering if there's any actual gain to be had from doing this now. I suspect the code from nodent is doing effectively this, but is more 'compliant' with promise behaviours. Perhaps I can ditch my code - out of curiosity how does the nodent solution deal with very deep recursion/long chains? In the code above, I'm having to fire a real promise once in a while from Node in order to clear out some of the call stack. -Steve |
The implementation of Thenable is in nodent/lib/thenable.js and nodent/lib/runtime.js lines 13-25. Because nodent generates nested Promises, rather than chained ones, long chains aren't an issue. Similarly, it never releases Zalgo as it always generates code like In terms of deep recursion (or iteration of loops containing In the cases where I have to |
@steve-gray - I'm guessing you've got enough to work with for now, so I'll close this issue. Feel free to re-open if you need any more support. |
I know this isn't an 'issue', but I've been battling against this myself. Here's my scenaro:
In short, I'm using an async code path that is potentially async in some places - but actually 99% of the time - totally sync. What I've been finding is that Promise.resolve(cachedValue) would bounce off the queue, causing massive slowdown. Your module is a massive improvement I find over the naive Promise based approach.
Been trying to benchmark a scenario where I do 200,000 operations, and finding that I'm not getting a massive uplift from fast-async. I'm wondering if this is a Node 6.4 or Babel improvement, because I only get a material difference when using babel-plugin-transform-bluebird - but even then it's nowhere near as fast as a pure sync solution - there's a serious amount of performance being lost.
In short, async-to-generator with the transform-bluebird seems to achieve most of the same effect, however, if I modify the such that I remove any reference to async/await and only use the sync path I get:
The mysteries I'm facing:
The text was updated successfully, but these errors were encountered: