itch.io Spring Selects Series A
On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags

JavaScript's for loop is surprisingly fast

A topic by Turnaround Games created May 23, 2019 Views: 6,888 Replies: 1
Viewing posts 1 to 2
(13 edits) (+1)

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 

homepagetwitter - reddit

Hello! I just came here from reddit. I am not sure how the V8 engine does it specifically, but JavaScript is part compiled, part interpreted from what I know, some parts of the code will be JIT compiled, I think that is true for some predictable sections that will be called often, but maybe you will find a proper source on that (I read one a few months ago, but don't remember the source anymore).