7

A lot of developers, especially ones who haven't used Node.js in production, seem to believe that Node.js is faster than other interpreted languages such as PHP, Python, and Ruby.

These claims include:

  • Node.js/V8 is x times faster than y language.
  • The JavaScript reactor pattern will always handle concurrency better than any multi-threaded application.

I can certainly believe the first claim, yet I am unable to find any satisfactory benchmarks showing this. The second claim seems unfounded, or at least too absolute.

What are the characteristics of Node.JS and V8 that justify such claims?

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
Ten Bitcomb
  • 1,154
  • 1
  • 9
  • 14
  • The [Benchmarks Game](http://benchmarksgame.alioth.debian.org/) compares the performance of various open-source language implementations, including V8. Benchmarks are generally run on single-core and multi-core machines. You can download the sources to run the benchmarks yourself. However, benchmarks lie – those are not typical workloads being tested. – amon Feb 09 '15 at 17:41
  • 3
    What practical problem are you trying to solve here? – Robert Harvey Feb 09 '15 at 17:52
  • There isn't a particular problem I am trying to solve. I am attempting to evaluate claims. – Ten Bitcomb Feb 09 '15 at 17:53
  • 6
    Ah. Can you provide citations for these claims, so that we can properly evaluate them? – Robert Harvey Feb 09 '15 at 17:54
  • 1
    If you can give specific claims you would like refuted or confirmed, that might be a little clearer. I can gladly confirm various claims or refute various others with experience and explanations, but your claims are arbitrary because you're trying to encompass the entire internet's literature on a technology's performance abilities in them. Pick some specific - objective - claims if you want them confirmed or refuted. – Jimmy Hoffa Feb 09 '15 at 17:57
  • Perhaps I was too broad. I think what I will do is remove this question and replace it with one that has more specific claims/citations. – Ten Bitcomb Feb 09 '15 at 17:59
  • 2
    @Ravenstine Keep in mind that as long as it's formulated as a request for some external link, it's still going to be off-topic. You'd have to ask a different kind of question (e.g. What is it about Node.js/V8 that allows it to be faster than Python/Ruby/whatever?) – Doval Feb 09 '15 at 18:01
  • I'm voting to close this question as off-topic because it asks to compare the performance of different languages. A language is not a car; is not faster or slower than another one. – Arseni Mourzenko Feb 09 '15 at 18:02
  • @Doval Actually, I am less interested in the speed aspect and more with the claim about concurrency in reactor patterns vs multi-threading. Would it be better if I asked a question specifically about that subject? For example: "How can a reactor pattern handle concurrency better than multi-threading?" – Ten Bitcomb Feb 09 '15 at 18:04
  • 1
    Just edit your question to that effect, and we'll reopen it. That said, I think you're still going to need to provide citations, because the answer almost certainly includes an "it depends" component. – Robert Harvey Feb 09 '15 at 18:05
  • 1
    @MainMa: you are nitty, the OP obviously is asking for a comparison of real language *implementations*, not languages. – Doc Brown Feb 09 '15 at 19:07
  • 2
    FWIW, I implemented the first ~130 Project Euler problems in node.js for learning. I was really astonished about the speed when I tried to reimplement some of them in C# and Visual C++ for optimization purposes, which got me far less improvement than I expected. For such kind of calculation programs, Node.js seems roughly to be equal to C#. Of course, you cannot apply those experiences when it comes to concurrency issues. – Doc Brown Feb 09 '15 at 19:13

2 Answers2

11

Let's have a look at the second claim.

The JavaScript reactor pattern will always handle concurrency better than any multi-threaded application.

To address this claim, I'm going to assume that concurrency in this context equates to scalability, since scalability is one of the primary motivations behind Node.JS. The distinction is subtle, but significant: there are many ways to get an application to scale better; concurrency is one way, but there are others. I'm also going to assume that NodeJS implements the reactor pattern, though I'm not going to describe it in great detail here.

By scalability, I mean "the ability to handle as many simultaneous requests as possible." The way that node.js does this is by providing an event loop. The event loop accepts a request from the client, and then immediately hands it off to "some other mechanism" for processing. It then returns control to the caller. This asynchronous approach allows node.js to accept many requests in a given time frame, and differs from other, more synchronous strategies, where the caller must wait for the result before continuing. The amount of processing that the event loop demands is quite small, so it is ready (or almost ready) most of the time to accept new requests.

What happens to the requests once they are handed off? Well, for purposes of our discussion, that's an implementation detail. A given request could be put into its own thread, or it could be queued on a thread containing others tasks. It could be handed to a Windows Service, or even sent to some other system for fulfillment.

The important thing to consider is the scalability that the event loop provides by making the acceptance of a request take as little time as possible. This doesn't require a separate thread for each request; all you really need are two threads (one to run the event loop, and the other to process the requests).

Naturally, if you want your request to be fulfilled in some reasonable time frame, you must throw some horsepower at the implementation detail I mentioned earlier. There is no free lunch. But that's a different practical concern than the scalability that arises by making sure that requests to a service are accepted rapidly, even though getting the results of those requests is deferred to some later time.

So when someone says something like "the reactor pattern handles concurrency better than multiple threads," they're being a bit imprecise. In a general way, they're comparing asynchronous techniques to multi-threading (asynchronous programming does not necessarily require new threads). The way I would say it is:

By using an event loop, you can abstract the acceptance of a request away from the fulfillment of a request, thereby improving scalability without incurring the unnecessary overhead of additional threads.

Further Reading

A Quick Introduction to How Node.js Works
Understanding the node.js event loop
Reactor: An Object Behavioral Pattern for Demultiplexing and Dispatching Handles for Synchronous Events

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
0

I've implemented SCrypt libraries both on the clientside and serverside using js-scrypt and CryptSharp, and found the results shocking.

With chrome, execution time was over twice as fast as the .net implementation.

I never really paid much attention to the V8 engine until I observed these performance results, but now I have a very healthy respect for javascript executing on V8.

As for multi-threading, JS is single threaded and non-blocking, so code must be written async by default. On a single processing core, javascript is basically forcing your code execution to be as processor efficient as possible, whereas serverside code can eat up threads and wait while other things are happening. So there are situations where there is work to be done and a core isn't doing work.

For well written multithreaded code with many cores, and enough work to keep them all busy, js's non-blocking single threaded code may not be able to compete. For example when simulating a universe on a super-computer.

However, thats not what Node.js is for. The vast majority of server code isn't multi-thread optimized or even necessary, so non-blocking wins.

Andrew Hoffman
  • 456
  • 4
  • 14