Javascript код для замедления работы браузера

Я пишу библиотеку для WebWorkers, и я хочу проверить разницу между запуском script в потоке главной страницы, по сравнению с одним или несколькими рабочими. Проблема в том, что я не могу узнать из-за короткой функции, которая будет достаточно напрягать мой браузер, чтобы я мог наблюдать разницу.

Быстрый поиск не принес много, но может быть, просто не знаю, что искать; обычно я пытаюсь оптимизировать свой код, а не замедлять его...

Я ищу алгоритмы или шаблоны, которые могут быть легко реализованы в чистом Javascript, который не зависит от DOM или XHR, и который может иметь аргумент, переданный для ограничения или указания того, насколько далеко идет вычисление (без бесконечных алгоритмов ); 1s < avg time < 10s.

Дополнительные баллы, если они могут быть построены без рекурсии, и если они не будут подвержены значительным всплескам памяти, при этом они будут как можно более интенсивными.

Ответ 1

Попробуйте использовать очевидную (и плохую) рекурсивную реализацию для последовательность Фибоначчи:

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

Ответ 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);

Или любой номер, который вы хотите использовать.

Ответ 4

По какой-то причине Bogosort приходит на ум. В основном это алгоритм сортировки, состоящий из:

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

Он имеет среднюю сложность O(n * n!) с небольшой памятью, поэтому он должен замедлять работу довольно хорошо.

Основной недостаток заключается в том, что его время работы может быть от O(n) до O(inf) (хотя действительно, O(inf) маловероятно).

Ответ 5

Возможно, это то, что вы ищете:

    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. Поскольку современные браузеры могут выполнять более одного цикла в одной Milisecond, будет немного хвоста, который будет срезаться.

Обновление

Размышление об этом... на самом деле использование обратного вызова ouputFkt для более чем простого вывода может дать большую информацию. Вы можете передать метод, который использует некоторые общие свойства, или вы можете использовать его для тестирования использования большой памяти.

Ответ 6

Кажется, что все сложны. Почему не это?

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

Вычислить много квадратных корней вручную?

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

Ответ 8

/**
 * 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()
  }
}

Вызов этого метода замедлит код на указанное количество секунд (с точностью ~ 200 мс).