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

发布于 2024-12-10 18:55:55 字数 352 浏览 0 评论 0原文

我正在为 WebWorkers 编写一个库,我想测试在主页线程中运行脚本与在一个或多个工作线程中运行脚本之间的区别。问题是:我无法立即找到一个简短的函数,该函数会给我的浏览器带来足够的压力,以至于我可以观察到差异。

快速搜索并没有得到太多结果,但可能只是我真的不知道要搜索什么;通常我会尝试优化我的代码,而不是让它变慢...

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

如果它可以在不使用递归的情况下构建,并且不会导致大量的内存占用,同时仍然尽可能地占用处理器资源,那么就加分。

I'm writing a library for WebWorkers, and I want to test the difference between running a script in the main page thread, versus in one or more workers. The problem is: I can't find out of hand a short function which will strain my browser enough that I can observe the difference.

A quick search didn't return much, but it might just be that I don't really know what to search for; usually I try to optimise my code, not make it slower...

I'm looking for algorithms or patterns that can be easily implemented in pure Javascript, that do not depend on the DOM or XHR, and which can have an argument passed to limit or specify how far the calculation goes (no infinite algorithms); 1s < avg time < 10s.

Extra points if it can be built without recursion and if it does not incur a significant memory hog while still being as processor intensive as possible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

随遇而安 2024-12-17 18:55:55

尝试对 斐波那契数列 使用明显(且不好)的递归实现:

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)

Try using the obvious (and bad) recursive implementation for the Fibonacci sequence:

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

Calling it with values of ~30 to ~35 (depending entirely on your system) should produce good "slow down" times in the range you seek. The call stack shouldn't get very deep and the algorithm is something like O(2^n).

戏舞 2024-12-17 18:55:55
/**
 * Block CPU for the given amount of seconds
 * @param {Number} [seconds]
 */
function slowdown(seconds = 0.5) {
  const start = (new Date()).getTime()
  while ((new Date()).getTime() - start < seconds * 1000){}
}

slowdown(2)
console.log('done')

调用此方法将使代码减慢给定的秒数(精度约为 200 毫秒)。

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

slowdown(2)
console.log('done')

Calling this method will slow code down for the given amount of seconds (with ~200ms precision).

温馨耳语 2024-12-17 18:55:55

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

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

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

Generate an array of numbers in reverse order and sort it.

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;
}

This can be called like so:

slowDown(100000);

Or whatever number you want to use.

葬﹪忆之殇 2024-12-17 18:55:55

查看 Google V8 Javascript 引擎引用的基准测试代码

Check out the benchmarking code referenced by the Google V8 Javascript Engine.

情归归情 2024-12-17 18:55:55

出于某种原因,我想到了 Bogosort。基本上,它是一种排序算法,由以下部分组成:

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

它的平均复杂度为 O(n * n!) ,内存很少,因此它应该可以很好地减慢速度。

主要缺点是它的运行时间可能在 O(n)O(inf) 之间(尽管实际上,O(inf)可能性很小)。

For some reason Bogosort comes to mind. Basically it's a sorting algorithm that consists of:

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

It has an average complexity of O(n * n!) with little memory, so it should slow things down pretty good.

The main downside is that its running time can be anywhere from O(n) to O(inf) (though really, O(inf) is pretty unlikely).

牵你手 2024-12-17 18:55:55

每个人似乎都决心变得复杂。为什么不是这个?

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;
}

Everyone seems determined to be complicated. Why not this?

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

If you're concerned the browser will optimize the loop out of existence entirely, you can make it marginally more complicated:

function waste_time(amount) {
    var tot = 0;
    for(var i = 0; i < amount; i++)
        tot += i;
}
茶花眉 2024-12-17 18:55:55

也许这就是您正在寻找的:

    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回调不仅仅是输出可以提供很好的洞察力。您可以传递使用某些共享属性的方法,或者可以使用它来测试大量内存使用情况。

Maybe this is what you are looking for:

    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;
    }

This method will simply repeat a check in a loop

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

I figured since you do not want to test a real function, and even NP-Hard Problems have a ratio between input length and time this could be a easy way. You can measure performance at any interval and of course receive the number of loops as a return value, so you can easily measure how much threads interfere each others performance, with the callback even on a per cycle basis.

As an example here is how i called it (jQuery and Dom usage are here, but as you can see optional)

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

    threadTest(1000, outputFkt, 20);

});

A last Warning: Of course this function can not be more exact than JS itself. Since modern Browsers can do much more than one cycle in one Milisecond, there will be a little tail that gets cut.

Update

Thinking about it... actually using the ouputFkt callback for more than just output could give great insight. You could pass a method that uses some shared properties, or you could use it to test great memory usage.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文