I recently remarked on how JavaScript's forEach array method is very slow compared to using a standard for loop. One of the interesting results in that post was how fast JavaScript's standard loop was to begin with. So I wanted to add a little extra to highlight this.
In this post I'm going present a very simple benchmark comparing a standard for loop in JavaScript (using node) with an equivalent written in C. The benchmark will compute the sum of all the elements in an array squared.
JavaScript
The JavaScript implementation is given below.
The program was run using Node version 10.15.3.
const {performance} = require('perf_hooks') const dataSize = 32000000 const data = [] for(let i = 0; i < 32000000; i++){ data.push(i * Math.random()) } const begin = performance.now() let sum = 0 for(let i = 0; i < dataSize; i++){ sum += data[i] * data[i] } const end = performance.now() const timeElapsed = end - begin const loopTime = timeElapsed / dataSize console.log(`result: ${sum}`) console.log(`total time: ${timeElapsed} ms`) console.log(`time per loop: ${loopTime} ms`)
C
The C implementation is given below.
The programs was compiled using gcc with order three optimisations (gcc -O3). gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.11). The result of the sum is printed at the end to prevent it being optimised away by the compiler, it will not be the same result as in the JavaScript comparison as the data is randomly generated.
#include <stdlib.h> #include <time.h> float randomFloat(); int main(int argc, char const *argv[]) { int dataSize = 32000000; double* data = malloc(sizeof(double) * dataSize); for(int i = 0; i < dataSize; i++){ data[i] = randomFloat(); } clock_t begin = clock(); double sum = 0; for(int i = 0; i < dataSize; i++){ sum += data[i] * data[i]; } clock_t end = clock(); double timeElapsed = (double)(end - begin) / CLOCKS_PER_SEC; double loopTime = timeElapsed / dataSize; printf("result: %f \n", sum); printf("total time: %f ms\n", 1000 * timeElapsed); printf("time per loop: %f ms\n", 1000 * loopTime); return 0; } float randomFloat() { return (float)rand()/(float)RAND_MAX; }
Results
On my machine the C version takes around 32ms to complete. The JavaScript version takes 34ms. That's pretty incredible for a high level interpreted language. The team behind the V8 engine (the JavaScript engine used by Node) has clearly highly optimised standard for loops and array access. It's very impressive.
Anyway, thanks for reading. I hope some of you found this interesting / useful.
Turnaround Games