Hacker News new | ask | show | jobs
by pron 5147 days ago
Node's API is async. Under the hood everything is done via threadpools, same as in Java or any other stack. Your hardware knows how to run threads; that's all. Whether or not that's what's exposed to you as a programmer is a different story.

You don't actually get a performance boost from Node being "async". Node's async abilities simply give you transparent access to threads that are otherwise unavailable with javascript, and it's the threads giving you performance.

2 comments

I don't think this is true. Nodejs uses epoll/kqueue/select etc to multiplex access to multiple file descriptors from a single main thread.

The async API is actually a price to pay (spaghettification).

For example, the go language took a different approach: it created a cheap thread-like construct which doesn't incur in the biggest overhead of classical threading (namely pre-allocated linear stacks and context switching/sleeping requiring a systemcall; all this aided by the compiler), and a cheap mean of communication (channels).

Then, the whole core IO library was written using a multiplexing async model (epoll...), which communicates with the user part of the library via channels). The result is a blocking like API which under the hood behaves like an async implementation.

A similar goal is also met by http://www.neilmix.com/narrativejs/doc/ and other javascript 'weavers' which convert "sequantial looking" code into callbacks.

Yes, but at the end of the day, underneath it all, you gotta have threads because that's what the hardware understands. Even if you use hardware interrupts to detect IO, you still need a plain old thread to handle it. The only difference between various languages and runtimes is how you distribute tasks among the threads. Some environments provide green threads that have a partial stack, but even they are handed off to a thread pool (or a single thread) for execution.

It's been found that if you employ only a single thread (that can run any number of tasks) you get a performance boost over using a larger threadpool under some conditions, but a single thread wouldn't let you scale by taking advantage of all processors.

I feel that the cause of misunderstanding lies in the fact that "thread" in this context is usually means "thread based IO", which means that when a thread issues a IO request it remains blocked until the IO request returns, leaving CPU time to other threads. All this regardless how many processors you have; it works perfectly fine with single processors.

Async IO is different, it's a different patter of access to IO and as such it's orthogonal to any threading or multiprocessing that's going on in order to actually do stuff in response to that IO.

> It's been found that if you employ only a single thread (that can run any number of tasks) you get a performance boost over using a larger threadpool under some conditions, but a single thread wouldn't let you scale by taking advantage of all processors.

Indeed. Nodejs solution to this problem is to have a cluster of nodejs processes and a dispatcher process on top. So multiprocessing is done the "old way".

In that case, Java gives you both options: blocking IO and non-blocking, polling IO. Netty can use both, but most people use it with the non-blocking option. Experiments have shown that sometimes one is faster and sometimes the other.
Umm, hardware knows NOTHING about threads. Threads give you a very fake view of the hardware. Everything about threads is an emulation over the hardware layer, hence why they have a large memory overhead.
The CPU is aware of a thread's instruction pointer and stack pointer (that's how some CPUs are able to support hyperthreading). Perhaps it's possible that the OS could somehow manipulate that to implement threads that are not as heavyweight as "common" threads, but I'm not aware of any OS that does that. Threads are the only multiprocessing abstraction provided by the CPU and the OS (although now there are some new abstractions for GPUs).