Почему такая большая разница в производительности между сложными циклами и многими циклами - PullRequest
3 голосов
/ 13 июля 2011

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

http://jsperf.com/nested-fors-vs-iterative-fors

Я удивлен тем, насколько значительна разница.

Может кто-нибудь либо указать, почему мой тест плохой (что вполне может иметь место), либо объяснить, почему разница в производительности.

Спасибо!

1012 * IDB *

Ответы [ 3 ]

3 голосов
/ 13 июля 2011

Я не знаю, для чего вам нужны underscore.js и jQuery.Я написал небиблиотечную версию , которая сравнивает:

  1. 100 циклов по 10 циклов по 1 вызову в каждом (1000 вызовов)
  2. 100 циклов по 10звонки (1000 звонков)
  3. 200 петель по 5 звонков (1000 звонков)
  4. 1000 звонков по 1 звонку (1000 звонков)

Производительность каждого довольнопохоже.

Я думаю, что ваша проблема в том, что в первом случае 100 анонимных функций делают по 10 вызовов каждая.Второй - 1000 анонимных функций, каждый из которых выполняет один вызов.Скорее всего, это связано с созданием анонимных функций (хотя я не смотрел на связанные внутренние части используемых библиотек).

1 голос
/ 13 июля 2011

Я думаю, что в ваших тестах есть проблема с яблоками в апельсины - в первом тесте вы циклически перебираете массив целых чисел 1 * 100 раз, чтобы в общей сложности выполнить 100 ваших функций (что выполняет вашу функцию doSomething)10 раз для выполнения 1000 выполнений.)

Ваш второй случай повторяет цикл целых чисел 10 * 100 раз, что в общей сложности составляет 1000 выполнений 10 анонимных функций, каждая из которых вызывает вашу функцию doSomething один раз.Обход массива из 100 элементов 10 раз займет больше времени, чем один раз.Создание 10 анонимных функций и вызов их по 100 раз каждая, безусловно, требует больше усилий, чем создание одной анонимной функции и ее вызов 100 раз.Эти две вещи делают ваши тесты совершенно разными.

Попробуйте вместо этого:

function doSomething(a) {
  a * 10 + a * 1000000.0 / 50.0;
}
var range = _.range(100),
    total_runs = _.range(10);
_.each(total_runs, function(a) {
    _.each(range, doSomething);
});
1 голос
/ 13 июля 2011

В первом случае вы вызываете одну итераторную функцию 100 раз. Во втором случае вы вызываете 10 итерационных функций 100 раз. Это в 10 раз превышает количество вызовов функций. Я бы сказал, что причиной разницы являются накладные расходы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...