Javascript код для замедления работы моего браузера - PullRequest
15 голосов
/ 20 октября 2011

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

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

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

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

Ответы [ 8 ]

11 голосов
/ 20 октября 2011

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

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 голосов
/ 27 января 2019
/**
 * 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 мс).

2 голосов
/ 20 октября 2011

Ознакомьтесь с кодом бенчмаркинга , на который ссылается Google V8 Javascript Engine.

2 голосов
/ 20 октября 2011

Создайте массив чисел в обратном порядке и отсортируйте его.

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

Или любое другое число, которое вы хотите использовать.

1 голос
/ 25 октября 2011

Каждый, похоже, полон решимости. Почему не это?

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;
}
1 голос
/ 20 октября 2011

Может быть, это то, что вы ищете:

    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 для большего, чем просто вывод, может дать отличную информацию.Вы можете передать метод, который использует некоторые общие свойства, или вы можете использовать его для проверки большого использования памяти.

1 голос
/ 20 октября 2011

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

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

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

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

0 голосов
/ 20 октября 2011

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

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