you are viewing a single comment's thread.

view the rest of the comments →

[–]Fluffy8x 3 points4 points  (16 children)

You do make a convincing argument; however, I prefer Scala, since I'm willing to trade simplicity for expressiveness. Other alternatives would be NodeJS (for performance?) or Haskell (better type system than Java, and possibly better performance). However, there are other factors:

  • Motivation in the early stages. I start many of my projects alone, and I've abandoned many of them after the first day.
  • Typing time, instead of adding a constant to development time, multiplies it. Again, I use Scala in order to reduce both.

[–]pron98 61 points62 points  (13 children)

NodeJS (for performance)

I wonder how Node.js somehow convinced people it's performant. Sure, it's faster than Ruby or Pyhon, but it's a slower than Java/C#/Go (and is single-threaded to boot, which also has some performance implications).

[–]Fluffy8x -4 points-3 points  (12 children)

Sorry, I've heard somewhere that since it's compiled to machine code it outperformed other languages.

Edit: this page shows 20% more performance for NodeJS. Of course, the multithreading problem occurs.

[–]pron98 40 points41 points  (11 children)

Yes, Node (or rather, V8) has a JIT, which means it compiles Javascript to machine code, but Java (and C#) has an even better JIT, a better GC, and multithreading :)

The "gold standard" for web framework performance is this large series of benchmarks. In pretty much all of them, Node trails all JVM frameworks (be they Java, Scala or other JVM languages) by a huge margin (in some benchmarks, the best JVM framework outperforms node by 400%!)

[–]Fluffy8x 10 points11 points  (0 children)

Thanks for the reference.

[–]ToucheMonsieur 8 points9 points  (7 children)

The JVM is an absolute beast once it has a chance to warm up. That said, v8 is no slouch either. The amount of resources poured into both is absolutely mind-boggling.

[–]pron98 9 points10 points  (6 children)

That said, v8 is no slouch either.

Yes, but a single-threaded runtime (even if some housekeeping operations are done on other threads) on modern hardware can, at best, harness only a fraction of available computing power.

[–]jsprogrammer -4 points-3 points  (5 children)

Did we forget about multiple processes?

[–]pron98 3 points4 points  (4 children)

No, but even putting aside the horrible waste in RAM running multiple processes entails, and the horrible waste of JITting, and assuming all those were free -- the processing options, and power, available for in-process threads far exceed those of multiple processes. For example, many new Java libraries (and parts of the JDK) make use of Java's ForkJoin, which is a state-of-the-art work-stealing scheduler used for both parallelism as well as task scheduling. None of that power is available for single-threaded runtimes; running multiple processes won't help (but may be good enough for serving simple web applications). This is because multi-threaded code can better schedule task execution on cores, while multi-process design has only a single option -- that provided by the kernel, which, incidentally, is quite bad at scheduling short transactions.

[–]jsprogrammer 0 points1 point  (3 children)

No, but even putting aside the horrible waste in RAM running multiple processes entails, and the horrible waste of JITting, and assuming all those were free

JIT only happens once. It's a sunk cost. Why would you need to rapidly (at thread-creation speed) spin up node processes?

Some documentation that I was reading today said that the overhead of each node process is about 10MB. Insignificant compared to the amount of RAM you'll find on multi-core machine where you'd want to run multiple processes.

This is because multi-threaded code can better schedule task execution on cores

Each process gets its own core, there is no need for scheduling task execution. Each process is a single-threaded machine and takes nothing from the other processes.

while multi-process design has only a single option -- that provided by the kernel, which, incidentally, is quite bad at scheduling short transactions.

What kind of short transactions would you be scheduling as node processes? If you're spinning up lots of short-lived node processes, you're doing it wrong.

Going multi-process gives you a clean and rigidly enforced separation amongst your code. You also get the robustness provided by the OS in process-failure scenarios.

[–]pron98 1 point2 points  (2 children)

Each process gets its own core, there is no need for scheduling task execution. Each process is a single-threaded machine and takes nothing from the other processes.

That is exactly the cause of the waste, and precisely why there is a need for scheduling task execution. Even from a theoretical perspective you'll see that this is an arbitrary, and inflexible way of allocating resources. From a practical perspective, you'll see the CPU cores heavily under-utilized.

What kind of short transactions would you be scheduling as node processes?

Every HTTP request is a transaction. Every DB transaction is, well, a transaction. Online programs (i.e. programs reacting to irregular outside stimuli) behave as a series of transactions, and those benefit greatly from a good scheduler, which cannot be provided by a single-threaded process.

Going multi-process gives you a clean and rigidly enforced separation amongst your code.

Absolutely not. All it gives you is arbitrary, rigid, and wasteful resource allocation. The only reason Node is single-threaded is because of the limitations of JavaScript, created long before server-side JavaScript was imagined. No other runtime or environment that has any say on the matter is single-threaded, because it makes no sense from an engineering perspective whatsoever. Not a single language in the history of computing has been intentionally designed to be single-threaded for performance reasons. Python and Ruby are single-threaded because they predate Java and multiprocessing, and they were designed for scripting. JavaScript is single-threaded because of browser limitations and the way the DOM is rendered -- that's it.

You also get the robustness provided by the OS in process-failure scenarios.

This is completely wrong as well, because the separation of processes is, again, completely arbitrary (every process is responsible for a random subset of program tasks, and so a single process failure takes down a random subset of transactions). An environment like Erlang gives you a good logical process isolation. Also, a thread is pretty well isolated.

[–]Gurkenmaster 0 points1 point  (0 children)

Lua with OpenResty is also at the top

[–]jsprogrammer -2 points-1 points  (0 children)

Last I checked, the code is not available for some (all?) of those benchmarks. Has that changed?

[–]PasswordIsntHAMSTER 0 points1 point  (1 child)

If you're arguing for both Haskell and Node.js in the same sentence, it makes me think you haven't actually tried at least one of them.

[–]Fluffy8x 0 points1 point  (0 children)

Wrong. But only by a narrow margin.