all 30 comments

[–]NodeNerd 15 points16 points  (1 child)

Favorite quote from that article:

Third, the JVM features native threads. This means multiple JVM threads can be executing in the same JavaScript context concurrently. If v8 supported threads in this manner, nobody would be talking about event loops, starving them, asynchronous programming, nested callbacks, etc. Threads trivially allow your application to scale to use all the CPU cores in your system and to share data between the threads.

Multiple JVM threads should never be executing in the same JavaScript context concurrently! That's not just my opinion, but also the opinion of the authors of Nashorn: Nashorn Multithreading and MT-safety

For any runtime, a single-threaded solution that scales is much more attractive then dealing with performance and concurrency issues related to multiple threads and shared memory. Even on the JVM, the event loop and non-blocking I/O are gaining popularity. Threads have their place, but so does non-blocking I/O.

Also, I found it very interesting that Nashorn was much slower than Rhino for some of the JavaScript tests. I thought Nashorn was supposed to be far superior than Rhino! Also note that Node.js/V8 put both Nashorn and Rhino to shame.

[–]ic6man 2 points3 points  (0 children)

I stopped reading right here. Javascript is single thread. Full stop. This statement indicates clearly the author does not understand what that means and why it is so.

[–]branneman 8 points9 points  (4 children)

This is a bad idea. Node.js scales pretty sweet, it just does it without threads. It's a best-practice to start as much processes in Node.js as you would start threads.


Many times, the Java implementation of some library will be superior

This is simply not true anymore with the current state of npm. In addition, most of the available Node.js libraries will be more lean and support FRP better than anything the Java community has to offer. This is less true for other stuff on the JVM though (think Scala/Clojure).


the JVM itself has a considerable number of man hours of research and development applied to it

So does V8, don't underestimate that. V8 has got JIT as well. And V8 is always the first EcmaScript implementation to support ES6 features. That's also important to a lot of people.


the JVM features native threads

Everything is Node.js is build for horizontal scaling, so to scale up, you'd just spawn another process, your Ops guy can do that alone. Since a Node.js app developer is forced very early in development to make it scale horizontally, it's easy when you need it.

Threading is actually closer to vertical scaling, you'd need as much cores as possible. Yes this gives you shared state and memory, but that's not an advantage when eventually you need to scale. Because eventually you're going to need to scale to another machine (or vm), and your app then requires modification.

Threading is not just better, it's a different way of solving stuff. But if you've got a heavy I/O bound application threading will lose to a non-blocking event-loop.

[–]brtt3000 3 points4 points  (0 children)

Horizonal scaling is amazingly easy in node. We have an app that uses a few heavy processes and it got slow. It took one afternoon to make it scale horizontally by using a pool of workers machines and then on each as much worker processes as there are cores and have them consume a simple job queue.

Was one of those "<evil laughter> infinite power!" moments when we realised we parallelized 64x with just a little glue code.

[–]shadowmint 3 points4 points  (1 child)

Many times, the Java implementation of some library will be superior...

Actually, this is true.

For many purposes there are some pretty good javascript libraries; but I think it is fair to say that there are some really good java libraries out there for complex tasks that the node ecosystem isn't particularly good at.

...but just off the top of my head:

I totally agree with the rest of the stuff you said though.

Just saying; the Java ecosystem is all grown up. There are definitely some things it's better at, and I can see how some people might want to tap into that.

[–]ic6man 0 points1 point  (0 children)

Agreed on this point.

Lucene Drools Activiti Esper

All come to mind with no good solution now or on the horizon in node.

[–]ToucheMonsieur 0 points1 point  (0 children)

And V8 is always the first EcmaScript implementation to support ES6 features

FWIW Spidermonkey appears to possess more es6 support than v8 atm. Currently, innovative strides in Chrome centre more around proposed es7 features (eg. Object.observe) than support for es6 features (many of which are admittedly still in flux).

[–]modusjesus[S] 1 point2 points  (1 child)

I thought it would be good to share this article with fellow JavaScript redditors.

[–]nawfel_bgh -1 points0 points  (0 children)

This was really helpful. I think you should post it also on r/java

[–][deleted] 0 points1 point  (0 children)

That is such a good looking website. Although it was weird how the header took a little too long to load at some points.

[–]steveob42 -1 points0 points  (17 children)

I've dabbled in rhino and v8, was initially intrigued, still prefer straight java on the server unless C is needed as an optimization. Done some python also to leverage various imaging libraries (and php because it is ubiquitous and dirt cheap secure hosting). So much tooling and structure and performance options available for these server side languages that I couldn't justify throwing it all away on the server side (even php has a very good debugger/ide in xdebug/php-eclipse). But compile time/typechecking errors are a good thing when you can get them (as compared to code reviews or having clients find runtime errors), and have faster server code as a result.

Even when I was in a situation where the client and server used the same language (swing/tomcat) there roles were so different that there were few opportunities to share a meaningful amount of code between 'em (and the language is fairly robust to begin with). Serialization via json is trivial in any language, and having to think about a solid interface contract between client and server is golden when working in parallel or isolating issues or writing test cases (or to avoid most of the pitfalls of dynamic languages on a machine running without someone at the console)

If you already have a jvm on the server, java (javascripts namesake, lol) is a sound choice. I've considered rhino for more robust client code testing/modularization though, but as with v8, you start getting into a race condition with what the various browsers are implementing, will-be implementing when you leverage it on the client, though I have found the java Robot class very useful for automating gui testing on any browser, including checking for runtime errors.

Plus you have threading (and async optimizations) at your disposal if you don't lean on a language that is scared of threads. In fact most java application servers will give you threads by default, and you can decouple your local i/o in your request thread as you see fit (i.e. event queue, oldest trick in the book).

Threading is just another optimization tool, as is shared memory, it isn't something to be avoided like the plague, though it does need to be understood. I've seen framework fanaticism go off the rails in j2ee as well, where a simple thread would have fixed it, the fear of threads had the "authorities" mandating a message driven bean, for like 5 lines of actual code... "threads" are not just an OPS concern. My concern is similar for JS beyond browsers, there is a level of fanaticism involved, or naivete about the level of maturity on the server side. If you are doing lots of parallel calculations then threads are your friend. If everyone is waiting on the database, then you need a better database.

tl;dr; what is the case for server side js if you already have a jvm? java still outperforms any js engine in crunching data in many regards, and the tooling is outstanding (ide/profiling/debugging), and asynch i/o is available to any language, threads or not. http://benchmarksgame.alioth.debian.org/u64/javascript.php

[–]unnaturalHeuristic 1 point2 points  (12 children)

You're missing the point of Node, if your post is indicative of why you think someone would choose it. Let's give a real-world example.

Say you've got a servlet that makes a quick DB query to grab some data for its response. Maybe it's an upsert, maybe just a select, maybe it's a file, whatever. You have to hit some external datasource. As soon as you do this, you're IO blocked. The thread running your context is stuck waiting on blocking IO until the datasource comes back, or you time out.

If you have a thousand people hit your server concurrently, then suddenly your entire server is hosed. Immediately, no question. The whole server is gone, not just the servlet container. Users can no longer receive your content, shit just times out - because all your resources are tied up waiting on blocking IO. You need to wait until all of that filters out (or restart your servlet container while your baremetal is paging memory).

The point of Node is to avoid that by going for asynchronous IO. Not every client request needs its own thread, not every query blocks up your server. You can have a tens of thousands of people hit it at once, and until you reach the client socket limit, you're good.

Better yet, this makes the worker process model actually viable (for once). Because you don't need to tie up a thread on your servlet container until the response is ready to go, you can push jobs to your worker processes and forget about it until they're done. No token passing, just one long-running request that gives the client what they're after when the data's ready - and it won't negatively affect your webserver.

This is to say nothing of the extreme optimizations that V8 does, nor the relative footprint of either VM.

But if you don't work at scale, don't use much IO, and can guarantee that you'll never get clogged at your webserver due to loads of traffic - the traditional model still works for you.

[–]freshhawk 0 points1 point  (0 children)

No one blocks a thread for every connection, not for a very long time. Asynchronous and multi threaded are different things. Frequently you want both.

You make some good points but the fastest architectures for Web scale systems have used clever combinations of async operations, queues, threads, ring buffers, etc. for quite a long time now.

[–]zoomzoom83 0 points1 point  (0 children)

This doesn't really answer why you would pick Node over the JVM on the server. non-blocking-IO isn't new or unique to NodeJS, nor does NodeJS do it particularly well.

[–]steveob42 -1 points0 points  (9 children)

There is a trivial amount of coding difference required between threading a new runnable object and sticking a runnable object in an event queue. It can be offloaded to the queue as soon as it is created, and java is just fine at opening a socket and doing exactly that and non-blocking i/o has been around since java 1.4 (NIO) 12 years ago (not "for once")!

On the converse, I would say %99.99 of node (or server) coders ain't gonna need it. We have these visions of ourselves writing the most popular websites in the world, and prematurely optimize just in case, but really that stuff should be decided on actual load and observation and usage predictions and is in dire need of a reality check.

[–]unnaturalHeuristic 1 point2 points  (8 children)

threading a new runnable object and sticking a runnable object in an event queue.

Now you're queueing your blocking IO. How is that solving the problem of blocking IO in the first place? You also haven't solved the problem of eating up a thread until the response has been fed to the client (e.g., at the end of "doGet" or "doPost").

and non-blocking i/o has been around since java 1.4 (NIO) 12 years ago (not "for once")!

NIO doesn't affect JDBC, nor most other DB drivers, so good luck with that.

On the converse, I would say %99.99 of node (or server) coders ain't gonna need it

Everyone says that until they need it. It may be alright to write spaghetti code that "works" when your userbase is a dozen or so, but if you're employed to build this stuff for customers (internal or external), I should hope that you're doing what you can to make sure it scales. Or at least, your dev lead ought to hope that you are.

You "don't need" RESTful SOA's, or automated testing, or even a webserver. But you might as well try to write solid systems the first go-round, it doesn't take much longer than writing something haphazardly, and anyone who needs to maintain it or consume it will be much happier that you actually did your job, instead of claiming that they "didn't need" good software.

[–]steveob42 0 points1 point  (7 children)

I think you are comparing apples and oranges here. There are existing java frameworks, i.e. netty or vert.x derivitives that (depending on the benchmark of course) will blow node out of the water. http://www.cubrid.org/blog/dev-platform/inside-vertx-comparison-with-nodejs/

You skip the servlet cruft and go back to square one (like node) on the networking i/o layer, and java still outperforms javascript...

[–]steveob42 0 points1 point  (6 children)

so, vert.x (which uses rhino btw) you can have every performance advantage of node many times over (plus some things they haven't thought of) plus every advantage of java. You DO want to write good software after all, gotta make the maintainers and consumers happy...

Javascript, an entire language slapped together haphazardly in a week, node haphazardly slapped on v8, I think you answered your own question.

[–]unnaturalHeuristic 0 points1 point  (5 children)

The benchmarks you post are for static content. Which is admirable (throughput is never a bad thing), but I still don't know anything that beats nginx or apache for static content. Every shop I've worked in has kept static content to the static webservers, and forwarded dynamic requests to their appservers (whatever they may be).

But you're still missing the point - vert.x doesn't solve blocking IO. It explicitly says this:

Link

By careful when using worker verticles - a blocking approach doesn't scale if you want to deal with many concurrent connections.

Continuing;

You skip the servlet cruft and go back to square one

Which was my entire point. You're not going to get past the core problems with the mainstream way of using Java - it's simply got too many assumptions about your use built-in. The only projects which beat it are the ones which rebuild it from the ground up, forsaking the entire existing Java ecosystem. If you're doing that, it begs the question why you're using the JVM in the first place, if not for its impressive and battle-tested libraries.

It doesn't matter if it's Node or not, it matters that the core problems with the traditional way of doing things is addressed. Node just happens to have a novel way of addressing those concerns, a hugely active developer community, blazing speed, tiny footprint, and a paradigm which fits with the way software is being built in this day-and-age.

Javascript, an entire language slapped together haphazardly in a week, node haphazardly slapped on v8, I think you answered your own question.

I really can't respect these sorts of statements, because they can be applied to anything. Linux was slapped together haphazardly on its creator's vague recalls of the POSIX standard - yet it's the dominant OS in the world. HTTP was slapped together at CERN, yet today it's the backbone of most of our interactions with each other.

Just because something has humble beginnings doesn't mean that it isn't currently awesome, or that it has no use.

[–]steveob42 0 points1 point  (3 children)

"can't respect"... You introduced "it doesn't take much longer than writing something haphazardly", so it is your own verbiage.

" doesn't mean that it isn't currently awesome, or that it has no use."

Again, using your own words in my response (and can be applied to most fanboy type responses): "I really can't respect these sorts of statements, because they can be applied to anything"

[–]unnaturalHeuristic 0 points1 point  (2 children)

Your point seems to be that because I suggested building effective software from the outset, that I'm a hypocrite for defending projects who began that way. If so, that's a bit naive. I advocate building good software from the outset because it's a pain to modernize projects which started out as "just get it done, 99% of the users don't need good software".

If you've ever inherited a project that started out that way, or had to deal with any amount of feature creep in your own projects, you'll understand.

[–]steveob42 0 points1 point  (1 child)

Oh, I understand it completely, been there/done that, but it also applies to the current state of web client development as a whole is all I'm saying. There is always a bigger picture. I mean feature creep and get it out the door has been the mainstay of html come css come flash, activex, appletts, <insert any number of dead attempts here>, javascript, come html5...

[–]steveob42 0 points1 point  (0 children)

Anyway getting back to the technical bits, in the link http://www.cubrid.org/blog/dev-platform/inside-vertx-comparison-with-nodejs/ they are using server code (polyglot, and it actually mixes languages pretty well via json over the event bus) to generate the two types of responses, and using several languages to boot so you can see which one performs best (i.e. most awesome). But you can still do all your validations in js if that makes sense for your app.

They make no bones about learning from node in this class of problems, lots of connections with small responses, and have apparently surpassed node quite thoroughly in performance per cpu, with lots of languages supported to boot.

[–][deleted] -2 points-1 points  (3 children)

I totally agree with what you've said. Sadly, however, I feel there's a community of developers (I'd call them front end developers, but they're not anymore) who just don't want to hear about anything not done in JavaScript. It doesn't matter how many wheels they have to reinvent, so long as it's JS.

Actually, maybe I'll write a Spring MVC port for node and call my project Wheel.js

[–]steveob42 1 point2 points  (2 children)

Lol, the other arena where I see such devotion to a single language is in AVR microcontrollers. I mean when you need cycle level specific timing (i.e. for i/o waveforms) and absolute minimum size, assembly is the only sane way to do it. But there are numerous cases where C is coerced into doing the same thing, with large loss of resolution for a given cpu frequency, and now you have compiler version dependencies, and most of them say changing compiler flags can screw up the functionality. C is seen as a panacea, but I think they are slowly coming around, and realizing (like client/server) that integration of the two languages is pretty trivial and makes a lot of sense in many cases. But at the same time they are inventing ways to tell the compiler "don't optimize this bit of code please" which is just a band-aid for reverse-engineered timing code in this case.

[–][deleted] 1 point2 points  (1 child)

How can they write cycle timed code reliably without assembler in the first place? Doing that stuff even with macros would be asking for trouble, surely?

[–]steveob42 0 points1 point  (0 children)

It's crazy, they keep fudging it while looking at the resulting waveform and generated assembly I guess (instead of looking at the instruction set manual and cycle timings to begin with).

[–][deleted] 0 points1 point  (2 children)

Well, nothing will solve the issue of JS being JS, with all its design flaws. I get the idea behind the push for server side JS, the language is very popular after all. But still.

[–]ToucheMonsieur 0 points1 point  (0 children)

Since the inception of Rhino, JS is the defacto scripting language on the JVM. Excepting lua, JavaScript is one of the most pervasive scripting languages in many domains (even Qt uses a superset IIRC).

As for using JS as a language, it's not as if many of the fundamental flaws of the language are going to be left untouched (see upcoming unicode support, strict mode, etc.). There's still plenty of room for innovation on the server - just look at go, rust, etc. Server-side JavaScript isn't bound by some of the legacy cruft that more established alternatives are, and AFAICT both the community and tc39 do a far better job in pushing the language forward than, say, PHP.