Loop time execution in Javascript
让我们以下面的片段为例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | 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 ) |
从普通循环报告的执行时间与回调内部执行的循环之间存在差异。此外,如果在head中的script标记内运行它,与在developer控制台中执行它相比,执行时间存在差异,如图所示:
脚本标记的结果:MGXY1[0]
来自控制台(火狐)的结果:。
有人能解释为什么会发生这种情况,或者提供到任何资源的链接,在那里我可以找到任何与此相关的信息。如果您将链接的响应或文档中包含浏览器差异,也将不胜感激。
感谢您的时间和帮助。
performance.now() 是衡量性能的最佳选择。
https://developer.mozilla.org/en-us/docs/web/api/performance/now/现在
结束时间计算错误。在你的
mprofile 函数中,你在调用第一个console.log 之前,用普通代码计算一个diff,在第二个console.log 之后。因此,在一种情况下,您将与控制台的交互包括在您的度量中,在另一种情况下-不是而且,整个例子有点不正确。您应该创建一个类似于
loop 、reverseLoop 等函数,并测量调用它们之前/之后的时间。然后您应该测量回调中相同函数的时间。您应该运行每个案例至少10次,并检查avg times。
如果您使用的是chrome
1 2 | console.time('myTime1') console.timeEnd('myTime1') //myTime1: 5047.492ms |