Live data from Hacker News

Hard-won lessons: Five years with Node.js

blog.scottnonnenberg.com

91–100 of 365 posts

Re: Hard-won lessons: Five years with Node.js

#91
post #75
post #15

I can't imagine choosing to write Javascript on the server, but considering its popularity I'm wondering if I'm wrong. So I'm curious as to the reasons people chose Node.js and whether you would recommend it, anybody willing to share their experiences?

NodeJS has a handful of things that tend to get brought up. Callback soup and difficult error handling. Both are resolved by promises. Once you get the hang of promises, you are capable of doing concurrent asynchronous tasks in a manner that would be significantly more difficult in any other language. On top of that, NodeJS is very, very fast. Compared to Python or Ruby, straight computing is significantly faster, bu…

> Once you get the hang of promises, you are capable of doing concurrent asynchronous tasks in a manner that would be significantly more difficult in any other language.

What languages are you comparing against? It seems like asynchronous code is more difficult to write in NodeJS than in C#, Go, or Rust, and about the same as Java. I can write code in Java in a style similar to promises using ListenableFuture (Google Guava) or CompletableFuture (Java 8) [0].

I should also clarify that I don't think promises are the optimal approach to asynchronous code. I think you can do better, and the primitive "await" is an example of how. Bob Nystrom (munificient) wrote an article called "What Color is your Function?" [1] that does a good job describing the difficulties of promised-based async, and how await improves on it, and how Go does even better.

(From what I've read, JavaScript ES8 is supposed to include async/await, and NodeJS seems to have support for them. At that point you'll be able to program in standard JavaScript and use await, which will bring NodeJS up to parity with the first-tier languages.)

> On top of that, NodeJS is very, very fast. Compared to Python or Ruby,

Perhaps that's true compared to Python and Ruby, but not when compared to other high-performance runtimes like Java. The following three paragraphs are from a comment I previously wrote on this topic [2].

Folks might also be interested in the TechEmpower web framework benchmark [3]. The top Java entry ("rapidoid") is #2 on the benchmark and achieves 99.9% of the performance of the #1 entry (ulib in C++). These frameworks both achieve about 6.9 million requests per second. The top Java Netty server (widely deployed async/NIO server) is about 50% of that, while the Java Jetty server, which is regular synchronous socket code, clocks in at 10% of the best or 710,000 R/s.

NodeJS manages 320,000 R/s which is 4.6% of the best. In other words, performance-focused async Java achieves 20x, regular asynchronous Java achieves 10x, and boring old synchronous Jetty is still 2x better than NodeJS throughput. NodeJS does a pretty good job given that it's interpreted/JITed while Java is compiled, though Lua with an Nginx frontend can manage about 4x more. NodeJS is handicapped by having to orchestrate everything from its single thread.

I agree that asynchronous execution can provide an advantage, but it's not the only factor to consider while evaluating performance. If throughput is someone's goal, then NodeJS is not the best platform due to its concurrency and interpreter handicap. If you value performance then you'll chose another platform that offers magnitude better requests-per-second throughput, such as C++, Java, Rust, or Go according to [3] and [4]. But I'll grant it has better IO performance than many other dynamically typed languages.

Asynchronous execution also does not necessarily require explicit async programming. Other languages have as good or better async support -- for example, see C#'s `await` keyword. [1] explores async in JavaScript, await in C#, as well as Go, and makes the case that Go handles async most elegantly of those options. Java has Quasar, which allows you to write regular code that runs as fibers [5]. The code is completely normal blocking code, but the Quasar runtime handles running it asynchronously with high concurrency and M:N threading (similar to Go). Plus these fibers can interoperate with regular threads. Pretty gnarly stuff (but requires bytecode tampering). If async is your preference over Quasar's sync, then Akka might be up your alley instead [6].

Lastly, high performance servers don't necessarily require asynchronous code at the application layer; performance sensitive logic can often live in the library or framework e.g. Netty, reverse proxy e.g. Nginx, or in the OS's context switching.

> Because NodeJS is non-blocking, the core is IMMEDIATELY available to serve the next request once an asynchronous call is made (read from DB/Cache/HTTP call). Because of this, each core can serve thousands of simultaneous connections.

This also describes regular synchronous code with many threads. Once your application makes a blocking call, the operating system context switches to another thread (process). This is how boring old blocking Java code running on Jetty outperforms NodeJS in request-per-second benchmarks [3]. And you could take advantage of this in NodeJS too if it weren't for the fact that JavaScript execution occurs in a single thread!

For most typical applications, overall performance is more influenced by the efficiency of the runtime than it is by the concurrency/async strategy.

[0] https://github.com/google/guava/wiki/ListenableFutureExplain... and https://docs.oracle.com/javase/8/docs/api/java/util/concurre...

[1] http://journal.stuffwithstuff.com/2015/02/01/what-color-is-y...

[2] https://news.ycombinator.com/item?id=12341886

[3] https://www.techempower.com/benchmarks/#section=data-r11&hw=...

[4] https://news.ycombinator.com/item?id=12268988

[5] http://docs.paralleluniverse.co/quasar/

[6] http://akka.io/

Re: Hard-won lessons: Five years with Node.js

#92

Too many lessons learned and arbitrary rules to follow equals flaws with design/language design

What language does not have these kinds of problems? I have encountered them with every programming language.

Which "every programming language" are those?

Re: Hard-won lessons: Five years with Node.js

#93

Earlier quoted context omitted.

JavaScript is a scripting language. So is Python and Ruby. As a scripting language, excluding all bindings (files, networking, etc), JavaScript is substantially faster than Ruby or Python. Now, in terms of bindings, bindings to libuv are also fast. So node is not so much of a problem in itself. However the problem is how the language is being used: To say you can write a serious library or server code because you kno…

> As a scripting language, excluding all bindings (files, networking, etc), JavaScript is substantially faster than Ruby or Python. This makes no sense. They're all dynamically typed languages (avoiding the term "scripting languages" since it's pretty vague). The only reason for the difference in speeds between these languages is due to the quality of their interpreters, not the languages themselves.

> The only reason for the difference in speeds between these languages is due to the quality of their interpreters, not the languages themselves.

That's not entirely true; there've been fairly good write-ups on particular elements of language semantics for which support inhibits VM performance; for instance, there were particularly good write-ups a while back by the JRuby team (Charles Nutter, specifically, IIRC) on Ruby semantics that are problematic in that respect.

Obviously, that doesn't mean that the level of investment by major firms in the interpreters doesn't have an impact, and Node is definitely riding high on Google's investment in making V8 speedy for Chrome. But language differences do matter.

Re: Hard-won lessons: Five years with Node.js

#94

Earlier quoted context omitted.

> yet I still turn to Node.js for proof of concept projects because certain things are just quicker to implement. Why? Writing Java is really very fast these days, especially with IDE's. I can get a small web site serving JSON REST requests and memcache up in ten minutes with a simple Maven/Gradle build and full IDE integration.

The edit/refresh cycle starts to slow as the project grows in Java, but node has pretty close to zero startup time and is interpreted. That plus a repl supports a much more explorative coding style where things work as fast as you can add them. No JVM restarts, compilations, or going back to change types or api's in the middle of a thought.

> The edit/refresh cycle starts to slow

IDEA and Eclipse compile your code as you write it. And with Hotswap, you don't even need to redeploy anything. They also all offer REPL's that are much more sophisticated than anything Javascript has to offer.

I think you haven't used a JVM language and its ecosystem in a very long time.

Re: Hard-won lessons: Five years with Node.js

#95
post #15

I can't imagine choosing to write Javascript on the server, but considering its popularity I'm wondering if I'm wrong. So I'm curious as to the reasons people chose Node.js and whether you would recommend it, anybody willing to share their experiences?

JavaScript is a scripting language. So is Python and Ruby. As a scripting language, excluding all bindings (files, networking, etc), JavaScript is substantially faster than Ruby or Python. Now, in terms of bindings, bindings to libuv are also fast. So node is not so much of a problem in itself. However the problem is how the language is being used: To say you can write a serious library or server code because you kno…

I think a lot of that is baloney. Not all apps require the same degree of rigor. In fact most require quite little. If a library is widely used, that's a pretty good indication it's "safe".

Re: Hard-won lessons: Five years with Node.js

#96
post #15

I can't imagine choosing to write Javascript on the server, but considering its popularity I'm wondering if I'm wrong. So I'm curious as to the reasons people chose Node.js and whether you would recommend it, anybody willing to share their experiences?

V8 is a world class compiler. Compared to ruby, Python, Erlang, php and that ilk it is lightning quick. (Pypy is a good match for it but it's not main street and you can't just use any module.) in terms of performance and popularity, v8/node stand pretty much alone as far as dynamic non-compiled environments. JavaScript has a lighter weight feel than Java and the jvm stack. Single threaded with a top notch event reac…

> Both it and dart vm are limited to relatively small memory footprints (think 1GB) which just isn't good for some workloads and problems.

This hasn't been true for a while now.

node --max-old-space-size=8192 server.js

See also http://prestonparry.com/articles/IncreaseNodeJSMemorySize/

Re: Hard-won lessons: Five years with Node.js

#97
post #75
post #15

I can't imagine choosing to write Javascript on the server, but considering its popularity I'm wondering if I'm wrong. So I'm curious as to the reasons people chose Node.js and whether you would recommend it, anybody willing to share their experiences?

NodeJS has a handful of things that tend to get brought up. Callback soup and difficult error handling. Both are resolved by promises. Once you get the hang of promises, you are capable of doing concurrent asynchronous tasks in a manner that would be significantly more difficult in any other language. On top of that, NodeJS is very, very fast. Compared to Python or Ruby, straight computing is significantly faster, bu…

> Once you get the hang of promises, you are capable of doing concurrent asynchronous tasks in a manner that would be significantly more difficult in any other language.

FYI, anyone who has worked with Elixir or Erlang views these sort of statements about Node as completely ridiculous. The only languages right now that are making a serious effort to bring real concurrency to modern programming are Go and Elixir. Node with its single threadedness and global heap doesn't come close, since those are fundamental problems with JS. The papering over the defienct language concepts with attempts like promises don't address these issues at all.

Re: Hard-won lessons: Five years with Node.js

#98
post #95

Earlier quoted context omitted.

JavaScript is a scripting language. So is Python and Ruby. As a scripting language, excluding all bindings (files, networking, etc), JavaScript is substantially faster than Ruby or Python. Now, in terms of bindings, bindings to libuv are also fast. So node is not so much of a problem in itself. However the problem is how the language is being used: To say you can write a serious library or server code because you kno…

I think a lot of that is baloney. Not all apps require the same degree of rigor. In fact most require quite little. If a library is widely used, that's a pretty good indication it's "safe".

Tror inte det blir brunch på stan på söndag

Re: Hard-won lessons: Five years with Node.js

#99
post #75
post #15

I can't imagine choosing to write Javascript on the server, but considering its popularity I'm wondering if I'm wrong. So I'm curious as to the reasons people chose Node.js and whether you would recommend it, anybody willing to share their experiences?

NodeJS has a handful of things that tend to get brought up. Callback soup and difficult error handling. Both are resolved by promises. Once you get the hang of promises, you are capable of doing concurrent asynchronous tasks in a manner that would be significantly more difficult in any other language. On top of that, NodeJS is very, very fast. Compared to Python or Ruby, straight computing is significantly faster, bu…

Is this satire? I can't tell anymore.

Re: Hard-won lessons: Five years with Node.js

#100
post #75
post #15

I can't imagine choosing to write Javascript on the server, but considering its popularity I'm wondering if I'm wrong. So I'm curious as to the reasons people chose Node.js and whether you would recommend it, anybody willing to share their experiences?

NodeJS has a handful of things that tend to get brought up. Callback soup and difficult error handling. Both are resolved by promises. Once you get the hang of promises, you are capable of doing concurrent asynchronous tasks in a manner that would be significantly more difficult in any other language. On top of that, NodeJS is very, very fast. Compared to Python or Ruby, straight computing is significantly faster, bu…

> you are capable of doing concurrent asynchronous tasks in a manner that would be significantly more difficult in any other language.

"any other language" is a bold claim. I heard Haskell gets concurrency more elegantly, or Erlang.

Post reply on HN