2013-03-10 108 views
0

我在Javascript中做了很多遞歸,爲了防止堆棧溢出,我一直在使用setTimeout。下面是一個簡單的理論例子:使用setTimeout的間隔小於1

go(){ 
    setTimeout(function(){ 
     x++; 
     go(); 
    },1); 
} 

我也有一個功能記錄x以每隔幾秒鐘控制檯,但這不是問題。我所看到的是,無論我在超時時間內輸入什麼值,在示例中使用了1,腳本每秒只能運行1000次。我正在做上億的遞歸,所以這個速度不夠快。當我將超時值設置爲0,或.1或1/10時,我仍然只能獲得每秒約1000次的時間。我試過使用32位和64位瀏覽器(Chrome和Firefox)無濟於事。

我該如何加快速度?而且,我在這方面都比較新,所以如果解決方案很簡單,那將會很棒。

哦,忘了提及:如果我完全刪除setTimeout,則每次都溢出堆棧。

感謝您的幫助!

+0

我不知道爲什麼你在客戶端瀏覽器做這樣的重操作。如果你能找到一種方法在你的服務器上運行它,它會更好。 – 2013-03-10 00:13:12

+3

我不確定我是否理解;如果您使用setTimeout來防止堆棧溢出,那麼您一定不需要遞歸。那麼,爲什麼你需要setTimeout?遞歸速度較慢只會延遲溢出。 – 2013-03-10 00:14:27

+1

你在做什麼看起來不太合適 – adarsh 2013-03-10 00:20:26

回答

1

我嘗試了一些和你一樣的東西,並找到了解決方案!您不需要遞歸和函數setTimeout,但是您需要的所有內容都是在for循環中重複使用所需函數setInterval以1個間隔重複。例如,如果for循環重複10次,那麼10個定時器將每4 ms執行一次相同的功能。代碼將會越來越快地被重複執行。

您的代碼應該是這樣的,例如:

function onload() { 
    for (var i = 0; i < 10; i++) 
     setInterval(go, 1); 
} 
function go() { 
    x++; 
} 
+0

這只是一種以相同的方式做更多的工作的方法,也是一種糟糕的方式。只需在函數中多次執行相同的操作,就可以獲得相同的結果,而且開銷較小。 – Guffa 2014-01-10 23:47:38

3

您的解決方案並不在於讓您的當前代碼運行,而是要重新考慮代碼。

我不知道如何在代碼中使用遞歸,但顯然你使用它是錯誤的。

對於遞歸的任何合理使用,您將遠遠沒有溢出堆棧。如果您將遞歸調用提升至數以億計的水平,那至少有一百萬倍以上。

使用遞歸的一種常見方法是將工作分爲兩個級別。這樣,您可以處理所有可以放入內存的物品,而不會超過大約30個級別。

1

JavaScript是單線程的,setTimeout會將您的操作放在隊列的末尾。即使你減少了延遲,你仍然必須等待以前的操作完成之前,你添加一個踢。

1

這是不可能使setTimeout等待少於4毫秒。這就是HTML標準中定義的setTimeout(官方規格here)。您的問題更可能是您的代碼的結構。向我們展示其餘的代碼,也許我們可以幫助解決它。

+0

根據您的參考,最小值爲4毫秒,而不是1(請參閱註釋) – Christophe 2013-03-10 00:37:10

+1

是的,看起來您是正確的。根據規範,該函數可讓您指定1 ms的延遲,但在內部將其提升至4ms。固定。 – 2013-03-10 00:43:09

+1

正確的,你甚至可以指定一個0毫秒的延遲 - 這通常被開發人員用來將執行移動到隊列的末尾。 – Christophe 2013-03-10 00:44:56

相關問題