Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NodeJS is faster than D when computing prime numbers. How?

I wrote a simple function for computing prime numbers in D. I thought it was pretty quick, calculating prime numbers up to 100,000. But then I wanted to compare it to NodeJS. When I ran the NodeJS script for the first time, I was astounded at the difference and double checked I wasn't skipping some sort of calculation some how. But the two are pretty identical functionally.

D:

import std.stdio;
import std.math;
import std.datetime;
import std.file;
import std.array;

enum size_t ITERATIONS = 100_000;

bool divisible(real n) {
    real d;
    for(d = 3; d < floor(n / 2); d += 2) {
        if(n % d == 0) {
            return true;
        }
    }

    return false;
}

void main() {
    StopWatch sw;
    size_t T = ITERATIONS;
    size_t C = 0;
    real n = 2;
    real r[ITERATIONS];
    r[C] = n;
    sw.start();
    C++;
    for(n = 3; n < T; n += 2) {
        if(!divisible(n)) {
            r[C] = n;
            C++;
        }
    }

    sw.stop();
    double seconds = cast(double)sw.peek().usecs / 1_000_000;
    writeln("\n\n", C, " prime numbers calculated in ", seconds, " seconds.");


    File file = File("primes.txt", "w");
    file.writeln("\n", C, " prime numbers calculated ", seconds, " seconds.");

    foreach(number; r[0..C]) {
        file.writeln(number);
    }

    file.writeln("\n", "end");
    file.close();
}

NodeJS:

var fs = require('fs');

var ITERATIONS = 100000;

function divisible(n) {
    var d;
    for(d = 3; d < Math.floor(n / 2); d += 2) {
        if(n % d == 0) {
            return true;
        }
    }

    return false;
}

(function() {
    var buffer  = [ ],
        now     = Date.now(),
        C       = 0
        n       = 2
        ;

    buffer.push(n);
    C++;
    for(n = 3; n < ITERATIONS; n += 2) {
        if(!divisible(n)) {
            buffer.push(n);
            C++;
        }
    }

    var time    = Date.now() - now,
        seconds = time / 1000
        ;

    console.log("\n\n", C, " prime numbers calculated. Process took ", seconds, " seconds.");
    buffer.push("\n" + C + " prime numbers calculated. Process took " + seconds + " seconds.");

    fs.writeFile("node_primes.txt", buffer.join("\n"), function(err) {
        if(err) throw err;

        console.log("Primes have been written to file.");   
    });
})();

Results:

Calculating 100,000 primes:
D:      3.49126 seconds
NodeJS: 0.652 seconds

Can anybody explain why this is happening?

Thanks in advance.

like image 448
thephpdev Avatar asked Oct 19 '14 14:10

thephpdev


1 Answers

By unnecessarily declaring variables as real, you are forcing floating point arithmetic where integer arithmetic could be used. Replace all instances of real with int, get rid of that floor() and your D program will run as fast as the Node.JS version:

import std.stdio;
import std.math;
import std.datetime;
import std.file;
import std.array;

enum size_t ITERATIONS = 100_000;

bool divisible(int n) {
    int d;
    for(d = 3; d < n / 2; d += 2) {
        if(n % d == 0) {
            return true;
        }
    }

    return false;
}

void main() {
    StopWatch sw;
    size_t T = ITERATIONS;
    size_t C = 0;
    int n = 2;
    int r[ITERATIONS];
    r[C] = n;
    sw.start();
    C++;
    for(n = 3; n < T; n += 2) {
        if(!divisible(n)) {
            r[C] = n;
            C++;
        }
    }

    sw.stop();
    double seconds = cast(double)sw.peek().usecs / 1_000_000;
    writeln("\n\n", C, " prime numbers calculated in ", seconds, " seconds.");


    File file = File("primes.txt", "w");
    file.writeln("\n", C, " prime numbers calculated ", seconds, " seconds.");

    foreach(number; r[0..C]) {
        file.writeln(number);
    }

    file.writeln("\n", "end");
    file.close();
}
like image 150
Stefano Sanfilippo Avatar answered Nov 15 '22 02:11

Stefano Sanfilippo