
What makes Node.js faster than Java? In a nutshell, it's all about concurrency - jguerrero
http://strongloop.com/strongblog/node-js-is-faster-than-java/
======
jerf
I have gotten to the point where I just can't take seriously anyone who
equates "the async style" to "Node's event based system" as if Go, Erlang,
Scala, Clojure, etc. don't exist. No, you _do not_ have to choose between
speed and sacrifice a sane coding style, and anyone still pushing that Node
propaganda is just not worth listening to.

Node is consistently beaten by multiple Go and Java frameworks across all
benchmarks [1], consistently beaten by Scalatra, somewhat inconsistently
beaten by the Haskell wai implementation (missing some benchmarks, I suspect
wai would continue winning though if they were implemented; also I think those
benchmarks are on an older Haskell IO manager). Not only are you choosing a
dangerous coding style, you're not even winning the performance you think you
are. Node is not faster. And certainly every library for Go, Haskell and
Erlang, and probably everything for Scala and Clojure (not 100% sure of their
runtime models) is already "async ready", and Java itself probably isn't
exactly running short of libraries at this point.

[1]:
[http://www.techempower.com/benchmarks/#section=data-r8&hw=i7...](http://www.techempower.com/benchmarks/#section=data-r8&hw=i7&test=update)

~~~
cdelsolar
Why is it a dangerous coding style? The new Node will have support for yield /
generators that result in beautiful async code.

~~~
hugs
Of course, beauty is in the eye of the beholder, but I would say yield
statements are not beautiful, they're just _less ugly_. Having lots of yield
statements sprinkled throughout my code is (again, in my eyes) ugly. Less ugly
than callback pyramids, but still ugly.

------
ebiester
At first, I was ready to dismiss this article completely. However, this
paragraph:

"While Java or Node or something else may win a benchmark, no server has the
non-blocking ecosystem of Node.js today. Over 50k modules all written in the
async style, ready to use. Countless code examples strewn about the web.
Lessons and tutorials all using the async style. Debuggers, monitors, loggers,
cluster managers, test frameworks and more all expecting your code to be non-
blocking async."

is true.

Java has had all of the same async capabilities for many, many years, but
nobody uses them because the blocking paradigm is simply easier.

That said, if true scalability is required, I'd suggest living with Akka and
the cleaner actors paradigm. However, it's true that eventually you're going
to run into the barrier that the vast majority of the java ecosystem is built
on blocking io.

(That said, with Java 8, I think we have a real opportunity to change that. I
think a parallel "lean java" ecosystem is coming.)

~~~
rdtsc
> no server has the non-blocking ecosystem of Node.js today. Over 50k modules
> all written in the async style, ready to use.

I read it as -- "Node.js doesn't properly support isolated units of
concurrency and thus due to being forced to write callbacks inside callbacks
that call errbacks for everything, we now have over 50k modules full of
callback chains and we call this a GoodThing(tm)".

~~~
chc
I don't think that's entirely fair. The standard callback model can easily be
converted to a promise-based one with Q or a CSP channel-based one with
ClojureScript's core.async or any number of other models.

~~~
rdtsc
It is but most of those module are not written like that.

For example Python's eventlet and gevent are based on greenlet. Greenlet is
based underneath on large select/epoll/kqueue/poll loop. So there are
callbacks for IO readiness there. However they manage to do some tricks to
hide that away behind green threads at the user level. So a user can say: "
authorize() ; check_database(); charge_credit_card(); update_database();
send_response()" logic properly for each request for example. Without having
to split that logic into a chain of callbacks just because some of them might
involve at some point making a socket call.

------
nobullet
I wouldn't be so sure with this statement: take a look at techempower's
frameworks benchmarks and compare best configurations of NodeJS and
PlayFramework (via genius Netty):

[http://www.techempower.com/benchmarks/#section=data-r8&hw=i7...](http://www.techempower.com/benchmarks/#section=data-r8&hw=i7&test=query)

NodeJS is far behind with 55% vs PlayFramework 67% on 20-queries test.

------
eigenrick
Yea. This headline has to be troll bait. NodeJS is not faster than Java, and
it's also not Concurrent. It is single threaded. It makes efficient use of
that single thread with an event-oriented model.

That said, I tend to prefer building in NodeJS because it's fast enough for
most (unanticipated) use cases.

~~~
nkozyra
Your operating system is concurrent even if it's single threaded.

Concurrency is about doing things _in the same time period_ not necessarily at
the exact same time.

~~~
nkozyra
That said, saying (concurrent) Node is faster than (nonconcurrent) Language X
is several distinct levels of stupid.

If you introduce blocking into an application then to the user it slower, but
in terms of computation it could still be faster by some magnitude.

It's like having C block on a network call while having in-browser Javascript
concurrently move past it and declaring Javascript faster.

~~~
drdaeman
> Language X

Actually, comparing runtime/platform (Node) to language is completely
pointless. Language is, well, only a language, it can't be "faster" or
"slower" unless we're talking about coding speed. We have to compare
implementations.

And even if we treat Java as a platform, contrary to Node it has ton of
highly-varying implementations, so it's still pointless without careful
clarifying what one compares. Or they may accidentally find out there's a Java
variation with green threads somewhere that may break the whole "look, their
ugly threads are slow and our event loops are fast" charm.

The article is just a pure load of non-sense. Highly flammable, though.

------
camus2
It's an "informercial" from a company which core business is providing nodejs
commercial tools and consulting, what did you expect them to say about NodeJS
?

------
rdtsc
> At high levels of concurrency (thousands of connections) your server needs
> to go to asynchronous non-blocking.

It does. But it doesn't have to expose that as callback chains or promises to
the whole over-arching infrastructure that sits on top. Concurrency units
should be isolated from each other and internally execute whatever their logic
is without having to worry about being polluted with callbacks. Then there
could be multiple of such concurrency units executing in parallel but that is
a the job of a decent VM/runtime/library to handle.

> And at these levels of concurrency, you can’t go creating threads for every
> connection.

Even something as simple as python gevent can create tens of thousands of
green threads without a problem without exposing callback chains for everyone
to see.

Erlang VM and something like
[https://github.com/puniverse/quasar](https://github.com/puniverse/quasar) can
run with millions of concurrency units so do goroutines and Rust's concurrency
units (sorry forgot the name).

> So the whole codepath needs to be non-blocking and async, not just the IO
> layer.

Quite the opposite. If your whole codepath riddled with callback chains and
your project is large now you have a huge headache to deal with.

> This is where Node excels.

If it forces one to use promises/deferreds/futures or nested callbacks, I say
it fails.

------
tedsuo
Systems such as Go's goroutines, or clojure's core.async, or objective-c's GCD
all solve the same concurrency problem while still allowing you to saturate
all of your cores from a single process.

This allows you to get around some nasty architectural problems you can hit
with node, where you must either find a way to manually schedule all of your
computation into tiny chunks to avoid latency issues, or face potentially
severe costs serializing your data to communicate it between processes. No
trolling here, it's really a thing that happens!

People do solve these problems in node, it's just that the "ease" suddenly
turns against you, as you must now solve tricky systems problems - such as
manually scheduling all of your computation properly - or face potentially
unacceptable performance degradation. In these cases the limitations of the
platform become your overriding architectural driver - better drivers like
logical separation start to take a back seat. It's not pretty - and not
necessary in other environments.

Given that you won't encounter these types of problems until later - once
you've already built up a large codebase and switching platforms is difficult
- I think it's better to start in an environment where you know you have these
tools available to you when you need them. Even though I really enjoy
programming in node (and I've done a lot of it!), I'm wary of starting
anything new there unless I have a good reason. There are a lot of great
modules written in node, I just try to keep those components isolated and not
let them grow too large.

------
weddpros
I'm not sure node.js is faster than Java... My experience shows the contrary,
but I switched to Node.js nonetheless. Node is fast... enough.

And socket.io justifies using Node :-)

------
manishsharan
I wish the author had considered middleware components written with Netty --
they are async and highly concurent as well.

Moreover, Servlet 3.1 Specification , which is a part of Java EE7, includes
JSR-340 Non-blocking I/O. In a typical application , ServletOutputStream and
InputStream do read/write in a while loop while holding on to the request
thread. This issue is potentially resolved in Servet 3.1 by adding event
listeners – ReadListener and WriteListener interfaces. These are then
registered using ServletInputStream.setReadListener and
ServletOutputStream.setWriteListener. The listeners have callback methods that
are invoked when the content is available to be read or can be written without
blocking.

The new versions of Glassfish and Tomcat servers already support Servlet 3.1.

So Java already supports async style web applications. The programmers have to
brush up their skills.

------
matt_heimer
"But there’s one thing we can all agree on: At high levels of concurrency
(thousands of connections) your server needs to go to asynchronous non-
blocking."

No, we can't all agree on that. Asynchronous non-blocking might be better in
limited scenarios where threads are expensive (memory or cpu or other
constraints).

"While Java or Node or something else may win a benchmark, no server has the
non-blocking ecosystem of Node.js today. Over 50k modules all written in the
async style, ready to use."

Sad to see so much work go into a faulty design. Take a look at this
presentation [http://www.slideshare.net/e456/tyma-
paulmultithreaded1](http://www.slideshare.net/e456/tyma-paulmultithreaded1).

------
programminggeek
Node is certainly not faster in many cases AND in many cases nonblocking IO is
NOT what you want. Sometimes sequential makes way more sense.

For example, I wrote a node script that would run a bunch of compilations of
files for custom less and javascript minifacation and other stuff on a large
codebase. Node opened so many file connections it would crush the machine and
not finish.

A simple bash script ran in about a second.

My point is you should definitely NOT use Node because you think it's faster
than Java in every case. In fact, evented everything is a pretty terrible
trade off in terms of code quality for performance.

There are so many better/easier/cheaper ways to get a high performance,
reliable system without using Node.

------
sheetjs
> Over 50k modules all written in the async style, ready to use

Is this even true? There are "57 210" modules in NPM at the moment but many of
them are explicitly synchronous

------
sheng
I'm always wondering why gevent never gets the same attention other
concurrency frameworks do. From my point of view it looks like a very sweet
library with useful tools and should work just fine in combination with
gunicorn or uwsgi. I never had a chance to test it with some real work load
though.

~~~
camus2
Problem is the lack of third party libraries that does IO the way gevent
works, if your lib does blocking IO, there is no point using gevent.

NodeJS does async IO by default,so all nodejs libs do async IO.

My point is , it's not so much about wether ruby or python can have the same
capabilities as nodejs they can,it's about wether async libs have an ecosystem
to support them or not.

~~~
jerf
"Problem is the lack of third party libraries that does IO the way gevent
works, if your lib does blocking IO, there is no point using gevent."

Here we probably see some of the problem. Gevent works in a way that most
people don't expect, which is to hack the IO layer itself. You don't need a
library to "support" gevent for it to still _work_ within gevent. If the
library's "synchronousness" is that it opens sockets and uses them, that Just
Works in gevent; every time the library does a "blocking" operation in gevent,
gevent replaces it with an entry in some sort of polling loop, and moves to
the next eventlet that can do work. I used it to write a highly concurrent
program that made a ton of simultaneous XML-RPC calls, and I used gevent + the
default "blocking" XML-RPC library from Python's core library. It _makes_ the
ecosystem support async, at least for network, timers (sleep), and a few other
things.

Gevent has other issues; I don't think it can do the same for disk IO. But
especially if you've got a network heavy program, you can just drop gevent in
and get perfectly cromulent async.

I think a lot of people don't quite understand this. The Node community's
persistent and vocal false belief that "async == visibly event-based structure
code" probably isn't helping. But it is also true that gevent is a
legitimately weird hack on a language. Cool, but very unusual.

~~~
drdaeman
One can monkey-patch __builtins__, too, so `open("foo", "r").read()` will
happily yield control to event loop. It's just that gevent doesn't do this.

Sounds like a great project to hack in spare time, though.

------
zinxq
Java blocking I/O is faster than non-blocking, at least on Linux. This is
kernel level, not language level.

[http://www.slideshare.net/e456/tyma-
paulmultithreaded1](http://www.slideshare.net/e456/tyma-paulmultithreaded1)

~~~
kasey_junk
You have to be very careful what you mean by "faster" in this case. For the
use case documented in those tests I assume he was measuring sustained
throughput (it isn't documented well what he means by 25% slower). He was also
testing a server that had lots of connections and not many messages per
connection. In that case modern Linux can scale threads very well.

I've done tests in other cases where NIO had nearly the sustained throughput
of the blocking libraries, but had much less jitter. That is the latency
through the server was much more consistent with NIO libraries than with the
blocking ones. This was in a protocol with few connections but lots of
messages per connection.

So blanket statements about the blocking IO vs the NIO libraries being faster
require more nuance than that.

------
_pmf_
What makes bullshit articles more common than valuable articles? It's all
about being a self-educated asshat with a lot of ego and second-order
ignorance.

------
uname1
Relevant: [http://vertx.io/](http://vertx.io/)

Polyglot, async, actor-like concurrent JVM platform.

------
smellelderberry
Node.js has linear speedup over multiple cores for web servers, no other
language can claim that.

~~~
drdaeman
Excuse me, but you've mistyped the word "any" in "any other language" part.

Last time I checked, event loops and async IO wasn't anything Node had
monopoly on. In fact, those are available on every non-toy general purpose
platform I remember off my head.

------
lemmsjid
One discussion that tends to not be had in these types of benchmarks is about
memory, resource utilization, and the fact that blocking is a feature.

In a typical multi threaded web application scenario, there's usually two main
resources floating around: http thread pools, and database connection pools.

Both are typically designed to not scale up too quickly (e.g. wait a bit
before adding a new resource) and block when they hit a configured maximum.
This is because it is pretty easy for a single web server these days to become
a denial-of-service attack on a database, and it's also pretty easy for a
single client (especially as the typical home's Internet bandwidth increases)
to become a denial-of-service attack on a web server. Sensible defaults should
therefore take into account that a web server should be a good actor in an
ecosystem, not that a web server should be a requests-per-second speed demon.
When I read benchmarks, I tend to believe that they are essentially testing
these defaults, because there is rarely discussion of them. A conservatively
tuned database connection pool will block earlier in the load test, but I will
respect the conservative defaults of the framework in question.

Memory is also crucially important in the sync-vs-async discussion. Once you
decouple request state management from a constrained-sized thread pool, you
have to predict how much memory each state will consume. Unless you are doing
very little work on each request (and the work will go up as you add
features), you will consume your web server's memory with request state far
before you exhaust its other resources. In a threaded model, the thread
overhead itself takes a lot of memory, so request overhead per thread in a
threaded model is higher than an async model. But when you're talking about a
web application with increasing numbers of features, this becomes less and
less the majority of the request.

Here's a sketch of an example. In the typical thread-pool based model, X
requests can happen simultaneously based on the configured maximum of handler
threads--if more requests come in than can happen at the same time, they go
into a queue. This is nice because unless the web application is very simple,
it's far easier to predict the memory overhead of http requests in a queue
than active simultaneous requests in the application layer, especially because
most web servers put maximums on the size of individual http headers. In other
words, the memory cost of each http request in the queue is constant, while
the memory-per-request-state in the application layer will grow with the
number of features that layer on the application.

Of course none of the above has much to do with asynchronicity vs thread-
bounded-ness. You can have a web server with a request queue and then a set of
asynchronous handlers that feed off the queue. I do have a weak argument for
threads in this scenario. In the constant tug-of-war between server resources
and request throughput, monitoring becomes very important. In a thread-based-
model, it is easy to use operating-system tools to introspect the threads
because the operating system knows what they are. In the asynchronous model
the process is a heap of undifferentiated ram. In that scenario you need good
tooling to predict how well tuned your request state is relative to resources.
In the JVM it's pretty easy to do a heap dump and see how much memory each
request is taking, I'm not sure if there's an equally convenient scenario in
the Javascript runtime(s) Node.js can utilize, but I'm sure there's a way.
What I do know, however, is that complexity increases as you add actors and/or
callbacks, because request state is now broken into a chain of independent
memory consuming entities, as opposed to a single predictable thread stack and
references.

In the midst of all the above I tend to go for flexibility, because the needs
are situational. Async when you need it, sync when you need it. With sync
being the more predictable model for the above reasons. Async is great for
socket servers that are fronting a fixed-sized memory store, like memcached,
while sync is more predictable (using today's tools) for a user facing web
application with non-fixed per-request costs.

Seriously, though, YMMV. The discerning reader will see that I'm not making a
fundamental argument for threads or async, because on one level there is no
difference between them. Threads are not coupled to CPU cores, so they
themselves are floating request state stack waiting to be scheduled by the OS
onto a core. Async request state is a further level of application level
decoupling where a pool of requests are waiting to be scheduled onto a thread,
which in turn will be scheduled onto a CPU. A second difference has nothing to
do with sync vs async but with coupling -- a synchronous model implies
utilizing a stack that executes one-at-a-time, while an asynchronous model
implies message passing (hence the ability for selective parallelism). Both
models have pros and cons when it comes to predictability and resource
utilization. The separation between the two will probably end up being a
historical artifact.

I'm just sketching some things that I think about when reading all these sync
vs async benchmarks, because they're kind of like saying that American cars
are slower than German cars because of average speeds on the Autobahn vs the
405 in Los Angeles, without a discussion of the posted speed limits, traffic
patterns, etc.

