使我的浏览器变慢的Javascript代码

时间:2011-10-20 18:20:48

标签: javascript algorithm web-worker

我正在为WebWorkers编写一个库,我想测试在主页面线程中运行脚本与在一个或多个worker中运行脚本之间的区别。问题是:我无法找到一个短暂的功能,这会使我的浏览器充满压力,以至于我可以观察到它们之间的区别。

快速搜索没有太多回复,但可能只是我不知道要搜索的;通常我会尝试优化我的代码,而不是让它变慢......

我正在寻找可以在纯Javascript中轻松实现的算法或模式,这些算法或模式不依赖于DOM或XHR,并且可以将参数传递给限制或指定计算的进度(没有无限的算法) ); 1s<平均时间< 10秒。

如果可以在没有递归的情况下构建,并且如果它在尽可能处理器密集的情况下不会产生大量内存占用,那么

额外点。

8 个答案:

答案 0 :(得分:11)

尝试使用Fibonacci sequence的明显(和错误)递归实现:

function fib(x) {
  if (x <= 0) return 0;
  if (x == 1) return 1;
  return fib(x-1) + fib(x-2);
}

使用~30到~35的值(完全取决于您的系统)调用它应该在您寻求的范围内产生良好的“减速”时间。调用堆栈不应该变得非常深,算法类似于O(2^n)

答案 1 :(得分:2)

以相反的顺序生成一组数字并对其进行排序。

var slowDown = function(n){
  var arr = [];
  for(var i = n; i >= 0; i--){
    arr.push(i);
  }
  arr.sort(function(a,b){
    return a - b;
  });
  return arr;
}

这可以像这样调用:

slowDown(100000);

或者您想要使用的任何数字。

答案 2 :(得分:2)

查看Google V8 Javascript引擎引用的benchmarking code

答案 3 :(得分:2)

/**
 * Block CPU for the given amount of seconds
 * @param {Number} [seconds]
 */
function slowdown(seconds = 0.5) {
  const start = (new Date()).getTime()
  let end = start
  while (end - start < seconds * 1000) {
    end = (new Date()).getTime()
  }
}

调用此方法将使代码运行速度降低给定的秒数(精度为〜200ms)。

答案 4 :(得分:1)

出于某种原因,Bogosort浮现在脑海中。基本上它是一种排序算法,包括:

while not list.isInOrder():
    list.randomize()

它的平均复杂度为O(n * n!),内存很少,所以它应该会减慢速度。

主要的缺点是它的运行时间可能是O(n)O(inf)之间的任何地方(尽管如此,O(inf)的可能性很小)。

答案 5 :(得分:1)

也许这就是你要找的东西:

    var threadTest = function(durationMs, outputFkt, outputInterval) {
        var startDateTime = (new Date()).getTime();
            counter = 0,
            testDateTime = null,
            since = 0, 
            lastSince = -1;

        do {
            testDateTime = (new Date()).getTime();
            counter++;

            since = testDateTime - startDateTime;

            if(typeof outputFkt != 'undefined' && lastSince != since && testDateTime % outputInterval == 0) {
                outputFkt(counter, since);
                lastSince = since;
            }
        } while(durationMs > since);

        if(typeof outputFkt != 'undefined') {
                outputFkt(counter, since);
        }

        return counter;
    }

此方法只需重复循环检查

durationMS - duartion it should run in miliseconds

OPTIONAL:
outputFkt - a callback method, for logging purpose function(currentCount, milisecondsSinceStart)
outputInterval - intervall the output function will be called

我认为既然你不想测试一个真正的函数,甚至NP-Hard问题都有输入长度和时间之间的比例,这可能是一个简单的方法。您可以在任何时间间隔测量性能,当然也可以接收循环次数作为返回值,这样您就可以轻松地测量线程干扰彼此性能的程度,甚至可以在每个周期的基础上回调。

这里的一个例子是我如何调用它(jQuery和Dom的用法在这里,但你可以看到可选的)

$(document).ready(function() {
    var outputFkt = function(counter, since) {
        $('body').append('<p>'+counter+', since '+since+'</p>');    
    };

    threadTest(1000, outputFkt, 20);

});

最后警告:当然这个功能不能比JS本身更准确。由于现代浏览器可以在一个毫秒内完成多个循环,因此会有一个小尾巴被切断。

<强>更新

考虑一下......实际上使用ouputFkt回调而不仅仅是输出可以提供很好的洞察力。您可以传递使用某些共享属性的方法,也可以使用它来测试大量内存使用情况。

答案 6 :(得分:1)

每个人似乎都决心要复杂。为什么不呢?

function waste_time(amount) {
    for(var i = 0; i < amount; i++);
}

如果你担心浏览器会完全优化循环,你可以使它稍微复杂一点:

function waste_time(amount) {
    var tot = 0;
    for(var i = 0; i < amount; i++)
        tot += i;
}

答案 7 :(得分:0)

手动计算大量平方根?

function sqrt(number, maxDecimal) {
    var cDecimal  = -1;
    var cNumber   = 0;
    var direction = -1;

    while(cNumber * cNumber !== number && cDecimal < maxDecimal) {
        direction = -direction;
        cDecimal++;

        while((cNumber * cNumber - number) / Math.abs(cNumber * cNumber - number) === direction) cNumber += direction * Math.pow(10, -cDecimal);
    }

    return Math.abs(cNumber);
}

function performTest() {
    for(var i = 0; i < 10000; i++) {
        sqrt(i, 3);
    }
}