Fabric Engine Benchmark: Node.js Fibonacci Server

November 29, 2011, Posted by Paul Doyle

Revision History

Date

Author

Description

29/11/2011

Peter Zion Initial version

Introduction

On 1 October 2011, Ted Dzuiba posted the entry “Node.js is Cancer” to his blog at
http://teddziuba.com/2011/10/node-js-is-cancer.html. One of his main points is that the single-threaded, non-blocking server architecture of Node.js can have very serious performance problems if any of the requests actually require the Node.js platform to perform a significant amount of CPU-bound work; this problem is compounded by the fact that JavaScript on its own can sometimes take significantly longer to execute a given CPU-bound algorithm than other languages. Many people responded with objections as to how the tests were performed as well as suggested solutions. However, Dzuiba’s point stood: Node.js, on its own, can have serious performance problems when confronted with per-request CPU work.

The purpose of the document is to demonstrate how Fabric Engine provides a solution to this problem. Fabric Engine is a high-performance computational engine that can be used from within Node.js. With Fabric Engine, a Node.js program can describe a computation to be performed, including any parallelism in the computation, and then request that Fabric Engine perform the computation; when the computation is done, the provided callback function is called, allowing the Node.js program to return the result to the requesting connection. While the computation is being performed the Node.js program continues to service other connections. Fabric Engine itself can make full use of all of the available CPU cores of the machine for both handling parallel elements within a single computation and for handling multiple calculations in parallel.

Test Platform

All tests were performed on an Amazon EC2 High-CPU Extra Large Instance (c1.xlarge) running stock 64-bit Ubuntu 10.10. No software other than the default system software was running on the machine at the time the tests were run. The specific instance characteristics (from Amazon) are:

  • 7 GB of memory
  • 20 EC2 Compute Units (8 virtual cores with 2.5 EC2 Compute Units each)
  • 1690 GB of instance storage
  • 64-bit platform
  • I/O Performance: High
  • API name: c1.xlarge

Test Description

The Fibonacci server benchmark is written in Node.js and uses the standard Node.js HTTP stack to respond to HTTP requests. For each incoming request it calculates the 40th Fibonacci number using the naïve algorithm used in Dzuiba’s original blog entry. There are two versions of the benchmark: one that written using pure JavaScript (which is exactly the same as that used by Dzuiba) and one that uses Fabric Engine to do the calculation of the 40th Fibonacci number. Both versions accepted requests from port 1337 of localhost.

For both versions, the Apache HTTP server benchmarking tool ("ab"; http:// httpd.apache.org/docs/2.0/programs/ab.html) was used to calculate the number of requests per second the server can handle. The number of concurrent requests was varied from 1 to 20, and for each number of concurrent requests the number of total requests was equal to four times the number of concurrent requests. For, for example, to run the test for 5 concurrent requests, the command line ab -n 20 -c 5 http:// localhost:1337/ was used. The ab tool was run on the same machine as the Node.js server.

All the source code for the tests is provided, open-source, in the Fabric Engine git repository at https://github.com/fabric-engine/Benchmarks/ in the directory Server/ Fibonacci.

Test Results

The following chart shows the number of requests per second fulfilled by the Node.js server on the test platform when running the pure JavaScript version and which running the version that uses Fabric Engine for computation:

Benchmarks Fibonacci

As Dzuiba points out in his blog entry, pure JavaScript using Node.js does not take any advantage of multithreading; even in the presence of many concurrent requests, only one request can be serviced at a time by Node.js. Furthermore, the evaluation of the Fibonacci number in JavaScript takes almost 5 seconds, resulting in a constant 0.2 requests served per second, independent of the number of concurrent requests.

In comparison, Fabric Engine serves about 2.4 times the number of requests per second even when only only one request happens at once; this is because the calculation of the resulting Fibonacci number happens entirely in native, optimized machine code. More importantly, however, Fabric achieves near-linear scaling in the number of requests served per second up to the number of available cores. Once the number of concurrent requests surpasses the number of available cores, Fabric is able to serve the requests at the rate that varies between 3.48 and 3.81 requests per second, up to the end of the maximum tested 20 concurrent requests.

It is important to note that, as in Dzuiba’s original blog entry, neither version of the Node.js server was run behind any sort of load balancer. It is expected that if the pure JavaScript version were run behind a load balancer it would achieve the same linear scaling in the number of cores but the number of requests per second would be about 2.4 times less than for the Fabric-enabled version as in the case of serial requests.

Download this post as PDF

Sign up for FE Server – Alpha

Comments

  • schmidh

    Thanks a lot for your post. Very helpful.