【问题标题】:Generating random unique data takes too long and eats 100% CPU生成随机唯一数据耗时太长,占用 100% CPU
【发布时间】:2012-08-07 09:01:11
【问题描述】:

警告:CPU 使用率达到 100%,小心。

Link to the jsFiddle

编写此脚本是为了设计一个动态蛇和梯形板。每次刷新页面时都会创建一个新版块。大多数情况下,所有背景图像都不会出现,CPU 使用率会上升到 100%。但有时它们都会出现并且CPU使用率正常。

Opera 显示一些背景图像,Firefox 滞后并询问我是否希望停止脚本。

我认为问题出在这几行代码上:

        for(var key in origin)      // Need to implement check to ensure that two keys do not have the same VALUES!
        {
            if(origin[key] == random_1 || origin[key] == random_2 || key == random_2)   // End points cannot be the same AND starting and end points cannot be the same.
            {
                valFlag = 1;
            }
            console.log(key);
        }

【问题讨论】:

    标签: javascript random unique


    【解决方案1】:

    您的算法非常无效。当数组几乎填满时,您实际上会进行数百万次无用的迭代,直到您运气好并且 RNG 不小心选择了丢失的数字。改写为:

    1. 生成一个包含所有可能数字的数组 - 从 1 到 99。
    2. 当您需要随机数时,在此数组的当前边界生成随机索引,拼接元素和此随机位置,将其从数组中删除并将其值用作所需的随机数。
    3. 如果生成的数字不符合您的某些条件(minDiff?),则将它们返回到数组。请注意,如果数组中的所有内容都无法满足您的条件,您仍然可以永远停止循环。

    您以这种方式从数组中提取的每个值都保证是唯一的,因为您最初用唯一的数字填充它并在使用时将其删除。

    我已经剥离了绘图并将生成的数字放入可以在控制台中检查的数组中。把你的图纸放回去,它应该可以工作了——现在会立即生成数字:

    var snakes = ['./Images/Snakes/snake1.png','./Images/Snakes/snake2.jpg','./Images/Snakes/snake3.gif','./Images/Snakes/snake4.gif','./Images/Snakes/snake5.gif','./Images/Snakes/snake6.jpg'];
    var ladders = ['./Images/Ladders/ladder1.jpg','./Images/Ladders/ladder2.jpg','./Images/Ladders/ladder3.png','./Images/Ladders/ladder4.jpg','./Images/Ladders/ladder5.png'];
    
    
    function drawTable()
    {
        // Now generating snakes.
        generateRand(snakes,0);
        generateRand(ladders,1);
    
    }
    
    var uniqNumbers = []
    for(var idx = 1; idx < 100; idx++){ uniqNumbers.push(idx) }
    
    var results = []
    
    function generateRand(arr,flag)
    {
        var valFlag = 0;
        var minDiff = 8;        // Minimum difference between start of snake/ladder to its end.
        var temp;
    
        for(var i = 0; i< arr.length; ++i) {
    
            var valid = false
    
            // This is the single place it still can hang, through with current size of arrays it is highly unlikely
            do {
                var random_1 = uniqNumbers.splice(Math.random() * uniqNumbers.length, 1)[0]
                var random_2 = uniqNumbers.splice(Math.random() * uniqNumbers.length, 1)[0]
                if (Math.abs(random_1 - random_2) < minDiff) {
                    // return numbers
                    uniqNumbers.push(random_1)
                    uniqNumbers.push(random_2)
                } else {
                    valid = true
                }
            } while (!valid);
    
    
            if(flag == 0)     // Snake
            {
                if(random_1 < random_2)        // Swapping them if the first number is smaller than the second number.
                {
                    var temp = random_1; random_1 = random_2; random_2 = temp
                }
            }
            else         // Ladders
            {
                if(random_1>random_2)        // Swapping them if the first number is greater than the second number.
                {
                    var temp = random_1; random_1 = random_2; random_2 = temp
                }
            }
            // Just for debug - look results up on console
            results.push([random_1, random_2])
        }
    }
    
    drawTable()
    

    【讨论】:

    • 好的,正在努力改进它......但你认为我的问题是因为算法效率低下吗?我认为这可能是......就像你解释的那样,这可能是由于你提到的僵局造成的。我的代码也会出现这种死锁。
    • 感谢工作!试了几十次,还没有死锁!有什么方法可以检查脚本是否已经运行了 x 段时间?这样我可以重新加载页面,如果它已经运行了超过 x 时间段。
    • @AbijeetPatro 作为一个快速的'n'dirty 解决方案,您可以在generateRand 顶部添加计步器,并在每次生成新对时勾选它,当它达到某个相当大的值时退出。
    【解决方案2】:

    我在 for 循环中使用“HighCharts”时遇到了这样的问题 - “浏览器”具有检测死脚本或无限循环的内置功能。所以浏览器停止或弹出一条消息说没有响应。不知道你有没有这种症状!

    这是由包含大量数据的“循环”造成的。我在 CodeProject 上写了一篇关于它的教程,你可以试试,它可能就是你的答案。

    http://www.codeproject.com/Tips/406739/Preventing-Stop-running-this-script-in-Browsers

    【讨论】:

      猜你喜欢
      • 2011-01-23
      • 2020-05-27
      • 1970-01-01
      • 1970-01-01
      • 2016-03-27
      相关资源
      最近更新 更多