11

async/await is available with node version 8. The code is linear for the first time in nodejs, natively. That is nice. Earlier many articles claimed that, in v8 javascript engine, a function with try/catch block is not optimized. Now, async/await requires try/catch blocks to deal with errors. So, as a developer what needs to be done to keep same the performance?

explorer
  • 944
  • 8
  • 18
  • Have you tried using `.catch()`? – guest271314 Sep 29 '17 at 04:37
  • @jfriend00 What specific pattern using `.catch()` at `async/await` are you referencing? `(async() => { "use strict"; await abc })() .then(result => console.log("resolved:", result)) .catch(err => console.error("rejected:", err))` – guest271314 Sep 29 '17 at 06:42
  • @jfriend00 No, do not gather which specific pattern you are referencing. – guest271314 Sep 29 '17 at 06:45
  • 1
    @guest271314 - Please stay on topic here based on the question. To catch a rejection at a higher level that occurs in a block where multiple `await` statements are used, you have to use `try/catch`. If you do not understand that, then please go read about `await` and rejections. I'm not going to educate you about that in the comments here. This is analogous to a `.catch()` used at the end promise chain, but when using multiple `await` statements instead of a promise chain, one cannot only use `.catch()` to catch the rejection at the higher level. – jfriend00 Sep 29 '17 at 06:47
  • 1
    I don't think you need to use try/catch, if you initiate with something like this: 'userService.logIn(req, res) .then(result => res.json(result)) .catch(error => next(error));' , every rejection / throw down the line (if not caught there) will be handled here. – PVermeer Apr 26 '18 at 09:41

2 Answers2

13

try/catch received TurboFan optimizations in commit 9aac80f for V8 5.3 (Node v7.x and above). This means that the historic statement that try/catch has bad performance is no longer true.
From V8 blog post:

In the past V8’s had difficulties optimizing the kind of language features that are found in ES2015+. For example, it never became feasible to add exception handling (i.e. try/catch/finally) support to Crankshaft, V8’s classic optimizing compiler. This meant V8’s ability to optimize an ES6 feature like for...of, which essentially has an implicit finally clause, was limited. Crankshaft’s limitations and the overall complexity of adding new language features to full-codegen, V8’s baseline compiler, made it inherently difficult to ensure new ES features were added and optimized in V8 as quickly as they were standardized.

Fortunately, Ignition and TurboFan (V8’s new interpreter and compiler pipeline), were designed to support the entire JavaScript language from the beginning, including advanced control flow, exception handling, and most recently for...of and destructuring from ES2015. The tight integration of the architecture of Ignition and TurboFan make it possible to quickly add new features and to optimize them fast and incrementally.


try/catch in an async function is just syntatic sugar over a Promise .then and .catch methods, and performance is therefore determined by the underlying Promise implementation. Bluebird claims to have better performance than native Promise implementations, so theoretically - if what Bluebird claims is true - you'll achieve better try/catch performance by overriding the native Promise implementation with Bluebird's Promise implementation.
For example, in Node: const Promise = require("bluebird"), or global.Promise = require("bluebird") to override it globally.

Note however that this might change in the future, as the original Promise implementation was in JavaScript, but has recently been re-implemented in C++ as can be tracked in bug #5343.

Community
  • 1
  • 1
Sven
  • 5,155
  • 29
  • 53
  • 1
    What does it mean to receive TurboFan optimizations? – jfriend00 Sep 29 '17 at 06:50
  • @jfriend00 TurboFan is one of V8's optimization compilers. Read more here: https://github.com/v8/v8/wiki/TurboFan – Sven Sep 29 '17 at 06:53
  • 1
    Yes, I know it's a type of optimization. The question asked is about `try/catch` performance with `async/await` in nodejs version 8 which you've not really offered any definitive information about. How fast is `await` now with `try/catch` compared to what it used to be? Or compared to programming without `async/await` and just using promises and `.catch()`? That's the kind of information that would actually answer the question. – jfriend00 Sep 29 '17 at 06:56
3

I found a Performance of native ES2015 promises and ES2017 async functions in Node.js v8

Performance of Callbacks vs Promises vs Async Functions in Node.js v8

Both native Chrome V8 ES2015 promises and ES2017 async functions perform roughly 2 times slower than Bluebird promises using almost 2 times more memory

and

Conclusion

Node.js v8 comes with significantly improved performance of native ES2015 promises and ES2017 async functions, further boosted by the introduction of native util.promisify.

ponury-kostek
  • 7,824
  • 4
  • 23
  • 31
  • Bluebird is Node.JS ? I thought Chrome V8 was the engine for Node. I am confused here, can you clarify please ? – Pac0 Sep 29 '17 at 10:37
  • 2
    @Pac0 `Bluebird` is user land implementation of `Promise` – ponury-kostek Sep 29 '17 at 10:58
  • 1
    The Bluebird package was super useful when Promises were not available natively. But their promise implementation is not fully spec compliant. That's why V8's implementation is slightly slower. The implementation has improved greatly though and is almost on par with BlueBird. I would use native promises, as you have spec compliance, no additional dependency, and you'll benefit from future engine optimizations. – user835611 Oct 09 '17 at 14:26
  • Bluebird is almost de-facto standard on Node.js. Many popular libraries do use it instead of standard promises, and the reason is the extended and convenient feature set. Web comes with an awful APIs, typically. Consider, for example, WebSocket. Assigning callbacks after initializing connection, lack of 2-phase initialization, lack of addEventListener() support, etc. – Brian Cannard Jun 13 '18 at 06:37