簡體   English   中英

為什么這個javascript這么慢? 這簡直是​​落后了嗎?

[英]Why is this javascript so slow? Is it simply down to lag?

請好好看看http://www.jhurleydesign.com/uniquerandom/

基本上,我創建的是一個隨機將這些白色星星變成綠色的腳本。 它的工作原理是生成唯一的隨機數,並使用每個數字作為eq選擇器來應用“綠色”類。

在我運行此代碼之前,我假設恆星變綠的速率會增加 ,因為潛在的eq選擇器的數量會越來越小。 (還記得我說他們是如何生成的唯一數字?“

然而,恰恰相反。 正如您在訪問該鏈接時所看到的那樣,星星會相對較快地變為綠色,但最后,腳本開始變得如此,因此非常慢。 在我的機器上,最后一顆星需要大約3分鍾才能變為綠色!

它落后了嗎? 如果是這樣,我怎么能繞過它呢? 這個腳本做了非常非常簡單的事情,所以我懷疑滯后是一個游戲阻止在這里。 我想我剛做了一個愚蠢的錯誤!

您可以從http://www.jhurleydesign.com/uniquerandom/復制並粘貼源代碼(全部在一頁上),但它也發布在下面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Greenstars</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
    var limit = $('span'),
        unr = [];
    setInterval(function () {
        {
            var random_number = Math.round(Math.random() * limit.length);
            if (unr.indexOf(random_number) == -1) {
                unr.push(random_number);
                limit.eq(random_number).addClass('green');
                if (limit.length < unr.length) {
                    alert('Finished!');
                };
            }
        }
    }, 0);
});
</script>
<style>
.green {
    color: #0F0;
}
#container {
    background-color: #000;
    color: #FFF;
}
</style>
<div id="container">
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
<span>*</span>
</div>

謝謝你的時間!

它將變得越來越慢,因為你為整個對象集生成一個隨機數,但是測試已經完成的對象。 因此,一旦只剩下幾個,就需要大量隨機數才能找到一個尚未轉動的數字。 另外,搜索已經轉動的越來越長的項目也變得越來越慢,盡管隨機數未命中可能是更大的交易。

最初創建一個包含所有星星的數組要好得多,當你轉一個時,將它從該數組中刪除。 然后在縮短的數組上創建隨機數。 你不必檢查它是否已經轉動,你的星星將從頭到尾以均勻的速度轉動。

這是代碼可以這樣編寫的一種方式:

// get array of DOM elements to operate on
var items = $('span').get();

var interval = setInterval(function() {
    var random_number = Math.floor(Math.random() * items.length);
    // add the class to the selected random item
    $(items[random_number]).addClass('green');

    // remove element we just processed from the array
    // so our random generator no longer includes it
    items.splice(random_number, 1);

    // if there are no more to do, stop the interval
    if (items.length === 0) {
        clearInterval(interval);
    }
}, 50);

僅供參考,我還將計時器間隔更改為50毫秒,因為您可能需要一個測量的動畫效果,而不是只需要盡可能快地將它們全部翻轉。 您可以將該時間值調整為您想要的任何值。 如果你想盡快翻轉它們,你只需:

$('span').addClass('green');

但是,我認為你實際上想要某種動畫,它應該在間隔上設置更具體的測量時間。

問題是你的功能是這樣做的

do this over and over again forever {
  Generate a random number
  if (random number has not been checked before) {
    mark random number as checked
    make the span at this random index green
    if (all spans are green) {
      show a message "finished"
    }
  }
}

因此,隨着時間的推移,您之前找不到隨機生成的數字的可能性越來越小 - 因此它可以在找到之前多次運行該函數。

當它下降到數字2或3時,循環可能會運行很長時間才會發生隨機落在2個剩余數字中的一個上。

你需要重新計算你的算法 - 最好隨機地隨機抽取你想要的每個數字的數組,然后按照這個順序使星星變綠,但是分開固定的時間。

另一種可能的算法是從數組中刪除您變為綠色的星星,然后生成1 - 新長度(前一個長度減去1)之間的隨機數

不要忽視所有關於如何提高效率的好建議,但為什么最后需要這么長時間只是概率問題。

我不知道你在屏幕上有多少*。 比方說1000,因為這是一個很好的簡單數字。 在你的第一個案例中,你有1000分之一的機會變成一個綠色。 在你取得第500次成功時,每次拿到一個數字時,你只有1000分中的500分。 在你取得第900次成功的過程中,你只有100分之一的機會找到新的比賽。 在你的最后一個,你繼續選擇隨機數,直到你的千分之一的機會發生。

從本質上講,將值存儲在數組中目前是無用的,因為它不會影響您選擇的下一個數字 - 它只會影響您是否將值設置為綠色。 在概率方面,這是“用替換畫”, 而不是 “無需替換”,如你所願。 你可以完全刪除你的陣列,你只需將綠色的東西變成綠色,然后等待很長時間,因為找到非綠色的幾率正在減少。 jfriend00的答案是讓你“無需更換”的答案 - 一旦你這樣做,是的,它會加速到最后。

問題是您將唯一的隨機數存儲在數組中並在該數組中進行線性搜索。

此外,您正在執行您的函數setInterval(..., 0)

試試這種方法。

  1. 你所有的跨度最初都有類“加載”。 <span class =“loading” > * </ span>
  2. 每次運行時刪除類
  3. 選擇隨機項和removeClass加載,並做任何你想做的事
  4. 計算仍有多少人仍在“加載”課程
  5. 不要忘記clearInterval以防止它再次運行。

演示http://jsfiddle.net/fedmich/QTy7G/

var objCont;
$(document).ready(function () {
    objCont = $('#container');

    function asteriks(){
        var items = objCont.find('.loading');
        if(items.length==0){
            //FINISHED
            alert('Finished!');

            clearInterval(interval_id);
            return false;
        }

       //pick random element, remove loading then addClass green
        var random = Math.round(Math.random()* items.length );
        items.eq(random).removeClass('loading').addClass('green');

    }
    var interval_id = setInterval( asteriks, 500);  
});

還有一些事情需要注意:

  1. 我將$('#container')存儲到變量objCont中,因此它被JQ查詢一次
  2. ClearInterval所以函數完成
  3. 我用了500ms,所以半秒鍾。 你真的需要它為0(從你的例子?)
  4. 這里還有另一種可能的改進,它只使用removeClass('loading')而不使用AddClass('green')技術,但那是另一個故事/案例

您已設置間隔計時器, 調用之間的間隔為0毫秒 這意味着瀏覽器基本上將花費所有時間來運行您的功能。 你期待世界上有什么?

您已從其中幾篇文章中看到了您的方法似乎變慢的原因。 這是一個相當線性的例子: jsFiddle示例

它的工作原理是構建一個span元素數組,然后隨機選擇一個並從數組中刪除它,基本上縮小池(數組長度)以從每次選擇直到長度為零。

var limit = $('span'),
    ary = [];
for (var i = 0; i <= limit.length; i++) ary.push(i);
function foo() {
    var random_number = Math.round(Math.random() * ary.length);
    limit.eq(ary[random_number]).addClass('green');
    ary.splice(random_number, 1);
    if (ary.length < 1) {
        alert('Finished!');
    } else {
        setTimeout(foo,5);   
    }
}
foo();

我個人喜歡這種方法 - http://jsfiddle.net/Y6xZG/2/

$(document).ready(function () {
    var limit = $('span').toArray();
    limit.sort( function() { return Math.random() > 0.5 } );

    var intv = setInterval(function () {
        if(!limit.length) {
            alert('Finished!');
            clearInterval(intv);
            return;
        }
        var $star = $(limit.pop());
        $star.addClass('green');
    }, 0);
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM