2014-10-19 8 views
5

मैंने डी में प्रमुख संख्याओं की गणना के लिए एक सरल कार्य लिखा था। मैंने सोचा था कि यह बहुत तेज़ था, 100,000 तक की प्रमुख संख्याओं की गणना करना। लेकिन फिर मैं इसे नोडजेएस से तुलना करना चाहता था। जब मैंने पहली बार नोडजेएस स्क्रिप्ट चलायी, तो मैं अंतर पर चौंक गया और दोबारा चेक किया गया कि मैं किसी तरह की गणना को कैसे छोड़ रहा था। लेकिन दोनों काफी समान रूप से समान हैं।नोडजेएस डी से तेज है। कैसे?

डी:

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."); 
    }); 
})(); 

परिणाम:

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

किसी को भी व्याख्या कर सकते हैं क्यों यह हो रहा है?

अग्रिम धन्यवाद।

+0

संकलक और डी के लिए कमांड लाइन? –

+0

मैं संकलन के लिए 'dmd/path/to/source.d' का उपयोग कर रहा हूं। – thephpdev

+0

'dmd -O -release -inline -boundscheck = off/path/to/source.d' के साथ प्रयास करें। –

उत्तर

7

अनावश्यक रूप से घोषित करने चर तक real के रूप में, आप चल जहां पूर्णांक गणित इस्तेमाल किया जा सकता बिंदु अंकगणित के लिए मजबूर कर रहे हैं। int साथ real के सभी बदल दें, कि floor() से छुटकारा पाने और अपने विकास कार्यक्रम Node.js संस्करण के रूप में के रूप में तेजी से चलेंगे:

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(); 
} 
+0

के लिए उपलब्ध नहीं है, जिसने मोच को मारा होगा। मैंने कोड को नोड.जेएस के खिलाफ करने की कोशिश की और गति के लगभग 1.8 प्राप्त किया। –

+0

हाय, यह हल किया गया। मुझे पता नहीं था कि असली उपयोग फ्लोटिंग प्वाइंट ऑपरेशंस को इस्तेमाल करने के लिए मजबूर कर रहा था। लेकिन दिलचस्प बात यह है कि, नोडजेएस से Math.floor() को हटाने के कारण यह 0.12 सेकेंड धीमी औसत तक चला गया .. – thephpdev

+0

डी में वास्तविक 'को सबसे बड़ी परिशुद्धता के साथ फ़्लोटिंग पॉइंट प्रकार के रूप में परिभाषित किया गया है। इसका मतलब है कि यह संभावित रूप से सबसे धीमा संख्या प्रकार था जिसे आप चुन सकते थे। दूसरी ओर, वी 8 रनटाइम संख्या संचालन पर अनुकूलन कर सकता है। उदाहरण के लिए, यह पूर्णांक ऑपरेशंस का उपयोग कर सकता है जब यह ज्ञात होता है कि पूरी संख्या का उपयोग किया जाता है। –