Earlier today I responded to a question with this answer. In the example that I posted, I used the synchronous version of a call in the bcrypt node module. I chose to use the synchronous version of the call primarily because I thought it made the response look a little cleaner, but I also didn't think that it would affect performance because bcrypt is cpu and memory intensive instead of I/O bound. It was my understanding that node ran almost all your code on a single thread like browsers do, and only used background threads for things like I/O and database access. This lead me to believe that cpu-intensive tasks would still essentially "block" the server, since there were no other threads to offload the work to.
A comment on my response indicated that my assumption was wrong, and after some research I realized that I did't really have a great grasp on how node.js handles this sort of thing. Does asynchronous programming in node.js speed up cpu and memory intensive calls? If so, how does it do it?
So why asyncio is faster than multi-threading if they both belong to asynchronous programming? It's because asyncio is more robust with task scheduling and provides the user with full control of code execution.
Since Node. js is single-threaded and non-blocking, you can achieve higher concurrency with the same resources". And when you read about what it's bad at it usually goes like this: "Since Node. js is single-threaded, CPU-intensive tasks will block all requests from completing, until the task is completed.
Node. js favors asynchronous APIs because it is single-threaded. This allows it to efficiently manage its own resources, but requires that long-running operations be non-blocking, and asynchronous APIs are a way to allow for control of flow with lots of non-blocking operations.
The single-threaded implementation makes Node a bad choice for CPU-intensive programs. When a time-consuming task is running in the program it blocks the event loop from moving forward for a longer period.
It depends on how the module is implemented.
If the module is implemented without any support for threading then yes, CPU bound processing cannot be done asynchronously. Some functions provide callbacks and my look asynchronous but they're really not. They actually run synchronously and blocks the event loop. Examples of this in javascript is Array.forEach()
.
But, modules may be implemented to do the processing in background threads. In which case it truly is asynchronous and can speed up CPU bound tasks. At the very least it frees up the event loop to handle incoming requests while the background thread is busy computing results.
An example of this is the crypto.pbkdf2()
function in node's own Crypto module.
But, how can modules execute code in other threads when node.js runs in a single thread?
The original way this was implemented was simply that the module wasn't written in javascript but was instead written in C/C++ and interfaced to node.js via it's addons API.
But these days even pure javascript modules and functions can spawn threads and/or processes. Node has an experimental module called Cluster that sets up a master/slave cluster of node processes. Your module or code can then run the CPU bound task in a worker process freeing up the main node process to handle the event loop. There are also several threading modules available on npm. Just search for "thread" on npmjs.org.
So, yes CPU bound tasks can be made to run faster or at least not block the main event loop by running asynchronously.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With