2011-11-18 8 views
10
काम पर

किसी ने मजाक में आपके ब्राउज़र निम्नलिखितजावास्क्रिप्ट Recursion सुधार

<html> 
<script type="text/javascript"> 
function crash(){ 
    for(i=0;i<5000000001;i++){ 
    document.write(i); 
    } 
} 
</script> 
<body onload="crash();"> 
</body> 
</html> 

था कि दुर्घटना करने का इरादा html फ़ाइल के साथ एक ईमेल भेजा फिर भी यह क्रोम और एक बातचीत में इसके बारे में एक बहुत अच्छा काम नहीं करता है यह उठने के लिए कि यह ब्राउज़र को उत्तरदायी या दुर्घटनाग्रस्त होने के कारण जितनी जल्दी हो सके 5,000,000,000 तक पृष्ठ गिनने के लिए जावास्क्रिप्ट लिख सकता है, यह देखने के लिए एक दोस्ताना प्रतिस्पर्धा तैयार की गई।

मैं क्रोम में उपयोग किए जाने वाले जावास्क्रिप्ट के निम्न टुकड़े के साथ आया था।

<html> 
<script type="text/javascript"> 
function countToFiveBillion(counter, num){ 
    if(num < 5000000000) 
    { 
    num++; 
    if(num % 18700 == 0){ 
     counter.innerHTML = num; 
     setTimeout(function() {countToFiveBillion(counter, num)}, 1); 
    } else { 
     countToFiveBillion(counter, num); 
    } 
    } 
} 
function initiateCountDown() 
{ 
    var counter = document.getElementById("counter"); 
    var num = +counter.innerHTML; 
    countToFiveBillion(counter, num); 
} 
</script> 
<body onload="initiateCountDown();"> 
<div id="counter">0</div> 
</body> 

</html> 

कारण यह है कि यह केवल क्रोम में चलेंगे कि मैं setTimeout कॉल उपयोग कर रहा हूँ क्रोम में एक stackoverflow बनाने से बचना है। (क्रोम आपको सभी ब्राउज़रों में से रिकर्सिव कॉल के लिए सबसे बड़ा ढेर भी देता है)।

क्या इस गिनती को किसी भी तेज बनाने के लिए मेरे पास कोई रास्ता है? मुझे लगता है कि मैं ओवरफ्लो (हालांकि कहीं 100 से कम) का कारण बनने से पहले थोड़ा सा गिनती राशि बढ़ा सकता हूं, केवल एक ही शर्त है कि जितना संभव हो उतना संख्या प्रदर्शित करना है।


बेहतर कोड:

<html> 
<script type="text/javascript"> 
var counter; 
var num = 0; 
function countToFiveBillion(){ 
    if(num < 5000000000) 
    { 
    num++; 
    if(num % 18701 == 0){ 
     setTimeout("countToFiveBillion()", 1); 
      counter.value = num; 
     } else { 
     countToFiveBillion(); 
    } 
    } else { 
     counter.value = "number greater than 5 Billion"; 
    } 
} 
function initiateCountDown() 
{ 
    counter = document.getElementById('counter'); 
    countToFiveBillion(); 
} 
</script> 
<body onload="initiateCountDown();"> 
    <input type="text" id="counter" value="0" /> 
</body> 

</html> 
  • बनाया गिनती और तत्व globabl
  • पाठ में इनपुट div के बजाय स्विचड
  • को अद्यतन यूआई ले जाया कॉलबैक

उत्तर

2
सेट करने के बाद

.innerHTML = ... का उपयोग न करें संख्या प्रदर्शित करें। this test के अनुसार, value इनपुट तत्व की संपत्ति सेट करना अधिक कुशल है।

<input type="text" id="counter" value="0" /> 
इसके बजाय एक नया कार्य के निर्माण की

, मैं वैश्विक/स्थानीय चर का उपयोग करने की सलाह देते हैं, और setTimeout लिए एक तर्क के रूप में एक समारोह संदर्भ गुजर, या init पर setInterval का उपयोग करें।

  • setTimeout(countToFiveBillion,0) के लिए setTimeout("countToFiveBillion()",1) स्वैप करें। स्पष्टीकरण: "countToFiveBillion()" अक्षम है; सबसे पहले, स्ट्रिंग को फ़ंक्शन में परिवर्तित कर दिया जाता है और कहा जाता है, फिर कोई अन्य फ़ंक्शन कॉल निम्नानुसार होता है। सुझाए गए फ़ंक्शन को केवल नए फ़ंक्शन किए बिना फ़ंक्शन को कॉल करना होता है। इसे एक दूसरे को विभाजित भी कहा जाता है।
  • सीमा लिफ्ट करें (मैं 18701 से 20000 तक बढ़ने में सक्षम था)। इस तरह के गोलाकार संख्या तक सीमा उठाने के बाद, मैंने देखा कि counter मान प्रत्येक समय-बाहर के बीच अद्यतन किया जाता है।
  • कार्यान्वयन में कुछ त्रुटियों को ठीक किया गया है (.innerHTML.value के साथ अन्य-ब्लॉक पर)।

प्रासंगिक कोड:

<input type="text" id="counter" /> 
<script> 
var counter, num = 0; 
function countToFiveBillion(){ 
    if(num < 5e9) 
    { 
     if(++num % 18701 == 0){ 
      setTimeout(countToFiveBillion, 0); 
      counter.value = num; 
     } else { 
      countToFiveBillion(); 
     } 
    } else { 
     counter.value = "number greater than 5 Billion"; 
    } 
} 
function initiateCountDown(){ 
    counter = document.getElementById('counter'); 
    counter.value = num; //Init, show that the script is 
    countToFiveBillion(); 
} 
window.onload = initiateCountDown; 
</script> 

फिडल: http://jsfiddle.net/KTtae/

+0

मुझे बिल्कुल यकीन नहीं है कि जेएस वाउडल में संदर्भ के रूप में फ़ंक्शन को कैसे पास किया जाए, मैं बस इस countToFiveBillion को जिस तरीके से कर रहा हूं उसके बजाय मैं कर रहा हूं? – msarchet

+0

वैश्विक रूप से चर घोषित करें, फिर 'setTimeout (..)' को 'setTimeout' (countToFiveBillion, 1) 'से प्रतिस्थापित करें। –

+0

आह हाँ, समझ में आता है – msarchet

0

WebWorker उदाहरण, index.html

<!DOCTYPE HTML> 
<html> 
<head> 
    <title>5 billion</title> 
</head> 
<body> 
    <input type="text" id="counter" value="0" /> 
    <script type="text/javascript" charset="utf-8"> 
     var 
      iCounter = document.getElementById('counter') 
      , counter = new Worker('worker.js'); 

     iCounter.value = 0; 
     counter.addEventListener('message', function (e) { 
      iCounter.value = e.data; 
     }, false); 
    </script> 
</body> 
</html> 

worker.js:

for (var i = 0; i < 5e9; i++) { 
    if (i % 18701 === 0) { 
     postMessage(i); 
    } 
} 

यदि आवश्यक हो तो गिनती को कई श्रमिकों में विभाजित किया जा सकता है।

संबंधित मुद्दे