为什么这个javascript这么慢?这简直是​​落后了吗?

时间:2013-02-14 23:58:46

标签: javascript jquery client-side

善待http://www.jhurleydesign.com/uniquerandom/

基本上,我创建的是一个随机将这些白色星星变成绿色的脚本。它的工作原理是生成唯一的随机数,并使用每个数字作为eq选择器来应用'green'类。

在我运行此代码之前,我假设恒星变为绿色的速率增加,因为潜在的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>

谢谢你的时间!

8 个答案:

答案 0 :(得分:9)

它将变得越来越慢,因为你为整个对象集生成一个随机数,但是测试已经完成的对象。因此,一旦只剩下几个,就需要大量随机数才能找到一个尚未转动的数字。另外,搜索已经转动的越来越长的项目数组也越来越慢,尽管随机数字丢失可能是更大的交易。

最初创建一个包含所有星星的数组要好得多,当你转一个时,将它从该数组中删除。然后在缩短的数组上创建随机数。你不必检查它是否已经转动,你的星星将从头到尾以均匀的速度转动。

以下是编写代码的一种方式:

// 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');

但是,我认为你实际上想要某种动画,它应该在间隔上设置更具体的测量时间。

答案 1 :(得分:5)

问题是你的功能是这样做的

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)之间的随机数

答案 2 :(得分:3)

不要忽视所有关于如何提高效率的好建议,但为什么最后需要这么长时间只是概率问题。

我不知道你在屏幕上有多少*。让我们说1000,因为它是一个很好的简单数字。 在你的第一个案例中,你有1000分之一的机会变成一个绿色。在你取得第500次成功时,每次拿到一个数字时,你只有1000分中的500分。在你取得第900次成功的过程中,你只有100分之一的机会找到新的比赛。在你的最后一个,你继续选择随机数,直到你的千分之一的机会发生。

基本上,将值存储在数组中目前是无用的,因为它不会影响您选择的下一个数字 - 它只会影响您是否将值设置为绿色。在概率方面,这是&#34;绘制替换&#34;,&#34;绘制而无需替换&#34;,如您所愿。你可以完全移除你的阵列,你只需将绿色的东西变回绿色,并且仍然等待很长时间,因为找到非绿色的几率正在减少。 jfriend00的回答是让你做的事情,无需更换即可。#34; - 一旦你这样做,是的,它会加速到最后。

答案 3 :(得分:1)

问题在于您将唯一的随机数存储在数组中并在该数组中进行线性搜索。

此外,您正在不断执行您的功能setInterval(..., 0)

答案 4 :(得分:1)

尝试这种方法。

  1. 您的所有跨度最初都是“加载”类。 &lt; span class =“loading”&gt; *&lt; / span&gt;
  2. 每次运行时删除类
  3. 选择随机项和removeClass加载,并执行任何您想要的操作
  4. 计算“加载”类
  5. 中仍有多少人仍在继续
  6. 不要忘记clearInterval以防止它再次运行。
  7. 演示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. 我使用500毫秒,所以半秒钟。你真的需要它为0(从你的例子?)
    4. 这里还有另一种可能的改进,它只使用 removeClass('loading')而没有 AddClass('green')技术,但这是另一个故事/案例

答案 5 :(得分:0)

您已设置间隔计时器,调用之间 0毫秒。这意味着浏览器基本上将花费所有时间来运行您的功能。你期待世界上什么?

答案 6 :(得分:0)

您已从其中几篇文章中看到了您的方法似乎变慢的原因。这是一个相当线性的例子: jsFiddle example

它的工作原理是构建一个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();

答案 7 :(得分:0)

我个人喜欢这种方法 - 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);
});
相关问题