简体   繁体   English

在Javascript中循环执行时间

[英]Loop time execution in Javascript

Lets consider the following snippet as example: 让我们考虑以下代码段作为示例:

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
    )

There is a difference between reported execution time from plain loops vs loops executed inside of callbacks. 报告的执行时间与普通循环和回调内执行的循环之间存在差异。 Furtermore there is difference in execution time if you run it inside of script tag in head vs execute it in developer console as shown in this images: 另外,如果你在头部脚本标签内部运行它而在执行时控制台中执行它,则执行时间会有所不同,如下图所示:

  1. Result from script tag: 脚本标记的结果: 脚本标记的结果

  2. Result from console (Firefox): 控制台(Firefox)的结果: Firefox中的控制台工具的结果

Can anyone explain why this is happening or provide links to any resource where I can find out any information related to this. 任何人都可以解释为什么会发生这种情况或提供任何资源的链接,我可以找到与此相关的任何信息。 Also would appreciate if browser differences would be covered in response or document you will link. 如果您将链接的响应或文档中涵盖浏览器差异,也将不胜感激。

Thank you for your time and help. 感谢您的时间和帮助。

  • performance.now() is the best option to measure performance. performance.now()是衡量绩效的最佳选择。

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

  • end time calculation is wrong. 结束时间计算错误。 in your mprofile function you calculate a diff BEFORE calling the first console.log , in ordinary code - AFTER the second one. 在您的mprofile函数中,您可以在普通代码中调用第一个console.log之前计算差异 - 在第二个之后。 so, in one case you include interaction with console into your measurement, in other - not 因此,在一种情况下,您将控制台与控制台的交互包含在您的测量中,而不是

  • also, the whole example is a bit incorrect. 另外,整个例子有点不正确。 you should create a functions like loop , reverseLoop , etc. and measure time before/after calling them. 你应该创建一个函数,如loopreverseLoop等,并在调用它们之前/之后测量时间。 then you should measure time for the same functions in callbacks. 那么你应该测量回调中相同功能的时间。 and you should run each case at least 10-times and check avg times. 你应该每个案例运行至少10次并检查平均时间。

If you are using Chrome console.time() is pretty useful. 如果您使用的是Chrome console.time()非常有用。 eg: 例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM