Подтвердить что ты не робот

Выполнение цикла в Javascript

Давайте рассмотрим следующий фрагмент в качестве примера:

var len = 1000000,
    testArr = []

    for (var i = 0; i < len; i++) {
        testArr.push(i+1)
    }

    function mprofile(name, subject, object) {
        var start = new Date().getTime(),
            result = subject(object),
            end = new Date().getTime() - start
        console.log(name)
        console.log('Result: ' + result)
        console.log(end)
    }

    var length = testArr.length,
        start = new Date().getTime(),
        cnt = 0

    for (i = 0; i < length; i++) {
        cnt += testArr[i]
    }

    console.log('Regular loop:')
    console.log('Result: ' + cnt)
    console.log(new Date().getTime() - start);

    start = new Date().getTime()
    cnt = i = 0
    for (i = length; i--; ) {
        cnt += testArr[i]
    }

    console.log('Reversered loop')
    console.log('Result: ' + cnt)
    console.log(new Date().getTime() - start);

    start = new Date().getTime()
    cnt = i = 0
    var startAt = length%8,
        iterations = Math.floor((length+7) / 8)

    do {
        switch (startAt) {
            case 0: cnt += testArr[i++]
            case 7: cnt += testArr[i++]
            case 6: cnt += testArr[i++]
            case 5: cnt += testArr[i++]
            case 4: cnt += testArr[i++]
            case 3: cnt += testArr[i++]
            case 2: cnt += testArr[i++]
            case 1: cnt += testArr[i++]
        }
        startAt = 0
    } while(--iterations)

    console.log('Duffs device')
    console.log('Result: ' + cnt)
    console.log(new Date().getTime() - start);

    start = new Date().getTime()
    cnt = i = 0
    iterations = Math.floor((length+7) / 8)

    switch (length % 8) {
        case 0: cnt += testArr[i++]
        case 7: cnt += testArr[i++]
        case 6: cnt += testArr[i++]
        case 5: cnt += testArr[i++]
        case 4: cnt += testArr[i++]
        case 3: cnt += testArr[i++]
        case 2: cnt += testArr[i++]
        case 1: cnt += testArr[i++]
    }

    while(--iterations) {
        cnt += testArr[i++]
        cnt += testArr[i++]
        cnt += testArr[i++]
        cnt += testArr[i++]
        cnt += testArr[i++]
        cnt += testArr[i++]
        cnt += testArr[i++]
        cnt += testArr[i++]
    }

    console.log('Optimized Duffs device')
    console.log('Result: ' + cnt)
    console.log(new Date().getTime() - start);


    mprofile(
        'Profiled regular loop',
        function(arr) {
            var cnt = 0,
                length = arr.length
            for (i = 0; i < length; i++) {
                cnt += testArr[i]
            }
            return cnt
        },
        testArr
    )

    mprofile(
        'Profiled reversed loop',
        function(arr) {
            var cnt = 0,
                length = arr.length
            for (i = length; i--; ) {
                cnt += testArr[i]
            }
            return cnt
        },
        testArr
    )

    mprofile(
        'Profiled Duffs device',
        function(arr) {
            var cnt = i = 0,
                length = arr.length,
                startAt = length%8,
                iterations = Math.floor((length+7) / 8)

            do {
                switch (startAt) {
                    case 0: cnt += arr[i++]
                    case 7: cnt += arr[i++]
                    case 6: cnt += arr[i++]
                    case 5: cnt += arr[i++]
                    case 4: cnt += arr[i++]
                    case 3: cnt+ = arr[i++]                     
                       case 2: cnt += arr[i++]
                    case 1: cnt += arr[i++]
                }
                startAt = 0
            } while(--iterations)
            return cnt
        },
        testArr
    )

    mprofile(
        'Profiled optimized Duffs device',
        function(arr) {
            var cnt = i = 0,
                length = arr.length,
                iterations = Math.floor((length+7) / 8)

            switch (length % 8) {
                case 0: cnt += arr[i++]
                case 7: cnt += arr[i++]
                case 6: cnt += arr[i++]
                case 5: cnt += arr[i++]
                case 4: cnt += arr[i++]
                case 3: cnt += arr[i++]
                case 2: cnt += arr[i++]
                case 1: cnt += arr[i++]
            }

            while(--iterations) {
                cnt += arr[i++]
                cnt += arr[i++]
                cnt += arr[i++]
                cnt += arr[i++]
                cnt += arr[i++]
                cnt += arr[i++]
                cnt += arr[i++]
                cnt += arr[i++]
            }
            return cnt
        },
        testArr
    )

Существует разница между сообщенным временем выполнения от простых циклов против циклов, выполняемых внутри обратных вызовов. Более того, существует разница во времени выполнения, если вы запустите его внутри тега script в голове и выполните его в консоли разработчика, как показано на этом рисунке:

  • Результат от тега script: результат script tag

  • Результат из консоли (Firefox): результат из консольного инструмента в Firefox

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

Спасибо за ваше время и помощь.

4b9b3361

Ответ 1

  • performance.now() - лучший вариант для измерения производительности.

https://developer.mozilla.org/en-US/docs/Web/API/Performance/now

  • Расчет конечного времени неверен. в вашей функции mprofile вы вычисляете diff, ПЕРЕД вызовом первого console.log, в обычном коде - ПОСЛЕ второго. поэтому в одном случае вы включаете взаимодействие с консолью в свое измерение, в другом - не

  • также, весь пример немного неверен. вы должны создать такие функции, как loop, reverseLoop и т.д., и измерить время до/после их вызова. то вы должны измерить время для тех же функций в обратных вызовах. и вы должны запускать каждый случай не менее 10 раз и проверять avg раз.

Ответ 2

Если вы используете Chrome console.time(), это очень полезно. например:

console.time('myTime1')
console.timeEnd('myTime1') //myTime1: 5047.492ms