Для быстродействия цикла в JavaScript - PullRequest
1 голос
/ 05 февраля 2011

Я прошел через http://www.youtube.com/watch?v=mHtdZgou0qU ускорил ваш javascript.

Итак, я сделал этот личный тест скорости:

    var count = 50000000;
    var testDummy;

    // test 1
    testDummy = 0;
    var test1Start = new Date().getTime();
    var i;
    for (i=0;i<count;i++) {
        testDummy++;
    }
    var test1End = new Date().getTime();
    var test1Total = (test1End-test1Start);

    // test 2
    testDummy = 0;
    var test2Start = new Date().getTime();
    var i
    for (i=count; i--;) {
        testDummy++;
    }
    var test2End = new Date().getTime();
    var test2Total = (test2End-test2Start);


    debug(
      "test1\n" + 
      "total: " + test1Total + "\n" + 
      "test2\n" + 
      "total: " + test2Total 
    );

Я получаю незначительные результаты, как иногда онидаже, а иногда нет.

Мой вопрос, если я использую для цикла, как это: "for(i=count;i--;)" это действительно быстрее?Я делаю что-то не так в своих тестах.

Спасибо за вашу помощь!

Ответы [ 4 ]

4 голосов
/ 05 февраля 2011

(я бы написал это как комментарий, но это было бы слишком долго.)

Во-первых: беспокоиться об эффективности цикла for почти всегда пустая трата (вашего собственного)время.Что внутри цикла, как правило, оказывает гораздо большее влияние на производительность, чем детали того, как указан цикл.

Второе: с какими браузерами вы тестировали?Различные браузеры будут показывать разные профили производительности;даже разные версии одного и того же браузера будут различаться.

В-третьих: не исключено, что движок JavaScript оптимизировал ваши циклы из картинки.Компилятор JavaScript может просто посмотреть на цикл и принять решение установить testDummy на 50000000 и покончить с этим.

Четвертый: если вы действительно хотите подорвать производительность, я бы попробовал for(i=count; --i != 0;) кака также for(i=count;i--;).Первый может сохранить машинную инструкцию или две, потому что выполнение вычитания (на шаге предкремента) может автоматически установить аппаратный флаг, указывающий, что результат равен 0. Этот флаг потенциально теряется, когда вы используете оператор постдекремента, потому что он не будетне проверяться до начала следующей итерации.(Шансы, что вы сможете заметить разницу, невелики.)

3 голосов
/ 05 февраля 2011

Ну ...

for( i=0 ; i < len ; i++ )

практически совпадает с

for( i = len ; i-- ; )

Давайте опишем это:

case 1: letя буду 0
логическим выражением
позвольте мне быть i + 1

case 2: позвольте мне быть len
позвольте мне быть i - 1
приведите меняк булеву (тип приведения) и интерпретировать ее.

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

Кстати, проверьте это:1023 *

var i = count;
while( i-- ) {}
0 голосов
/ 22 июня 2012

Я также провел несколько тестов, вот результаты.

Во многих статьях авторы книг предполагают, что «оптимизированные» циклы быстрее.

Кажется, что современные браузеры имеют некоторую оптимизациюдля "нормальных" циклов.

Firefox 13.0.1

  • Нормальный цикл: 0,887
  • Opt1: 1,025
  • Opt2: 1,098
  • Opt3: 1.399

Chrome 19.0.1

  • Нормальный цикл: 3.349
  • Opt1: 3.12
  • Opt2: 3.109
  • Opt3: 3.095

IE8

  • За 12 сек ...
  • Неоднократно падал во время испытаний.

<script type="text/javascript">

function p(p) { console.log(p); }
// function p(p) { document.write(p); }

var testFn = function(num, niz, fn) {
    var start = new Date().getTime();

    fn(num, niz);

    var result = (new Date().getTime() - start) / 1000;

    return result;
}

function normalLoop(num, niz) {
    for (var i = 0; i < niz.length; i++) {
        niz[i] = 'a' + i;
    }
}

function opt1(num, niz) {
    var len = niz.length;
    for (var i = 0; i < len; i++) {
        niz[i] = 'a' + i;
    }
}

function opt2(num, niz) {
    for (var i = niz.length; i--;) {
        niz[i] = 'a' + i;
    }
}

function opt3(num, niz) {
    while(i--) {
        niz[i] = 'a' + i;
    }
}

var niz = [];

var num = 10000000;

for (var i = 0; i < num; i++) { niz.push(i); };

p('Normal Loop: ' + testFn(num, niz, normalLoop));
p('Opt1: ' + testFn(num, niz, opt1));
p('Opt2: ' + testFn(num, niz, opt2));
p('Opt3: ' + testFn(num, niz, opt3));

</script>
0 голосов
/ 05 февраля 2011

В ваших тестах нет ничего плохого.

Блоки, которые вы тестируете, практически идентичны, что означает, что разница в скорости выполнения будет тривиальной. В обоих примерах переменная (i) устанавливается на фиксированное значение и повторяется до тех пор, пока не достигнет фиксированного значения (счетчика). Единственное, что отличается, это i ++ и i--, которые с точки зрения скорости, я думаю, практически одинаковы.

Вещь, с которой вам следует быть осторожным (не делать), - это вычислить значение «до цикла» внутри определения цикла.

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