· 7 years ago · Mar 11, 2018, 05:19 PM
1(function (window) {
2
3 var console = window.console,
4 BenchLog = "",
5 Bench = {},
6
7 BenchLogWrite = function(message) {
8 if (console && console.log) {
9 console.log(message);
10 } else { // no console logger
11 BenchLog += message;
12 }
13 },
14
15 BenchStart = function(benchName) {
16 if (console && console.time) {
17 console.time(benchName);
18 } else { // no console timer
19 Bench[benchName] = new Date();
20 }
21 },
22
23 BenchEnd = function(benchName) {
24 if (console && console.time) {
25 console.timeEnd(benchName);
26 } else { // no console timer
27 Bench[benchName + "End"] = new Date();
28 BenchLog += benchName + ":\t" + (Bench[benchName + "End"] - Bench[benchName]) + "ms\n";
29 }
30 },
31
32 BenchFunction = function(benchName, testTimes, benchFunction) {
33 // lower is better
34 BenchStart(benchName);
35 for (var i = testTimes; i--; ) {
36 benchFunction();
37 }
38 BenchEnd(benchName);
39 },
40
41 TimedBench = function(benchName, timeToRunMs, benchFunction, hideTime) {
42 // from John Resig, higher is better
43 var start = (new Date()).getTime();
44 var time = 0;
45 var score = 0;
46 while (time < timeToRunMs) {
47 benchFunction();
48 time = (new Date()).getTime() - start;
49 score++;
50 }
51 var status;
52 if (hideTime) {
53 status = benchName + ":\t" + score + "\n";
54 } else {
55 status = benchName + ":\tscore for " + timeToRunMs + "ms:\t" + score + "\n";
56 }
57 BenchLogWrite(status);
58 },
59
60 FlushBenches = function() {
61 if (!(console && console.time && console.log) && BenchLog && (BenchLog.length > 0)) {
62 window.alert(BenchLog);
63 BenchLog = "";
64 }
65 },
66
67 // loop functions for determining the fastest way to enumerate an array
68 TestArrayLoop = function(arrayToBenched, benchName, units, arrayFunction, benchFunction, hideTime) {
69 // try various loops on array, variations from Steve Souders
70 // NOTE: don't modify arrayToBench in arrayFunction(arrayToBench[i]) - it would be "bad"
71
72 if (hideTime) {
73 BenchLogWrite(benchName + " (score for " + units + "ms):\n");
74 } else {
75 BenchLogWrite(benchName + ":\n");
76 }
77
78 benchFunction(benchName + ": Standard", units, function() {
79 for (var i = 0; i < arrayToBenched.length; i++) {
80 arrayFunction(arrayToBenched[i]);
81 }
82 }, hideTime);
83
84 benchFunction(benchName + ": length var", units, function() {
85 for (var i = 0, iLength = arrayToBenched.length; i < iLength; i++) {
86 arrayFunction(arrayToBenched[i]);
87 }
88 }, hideTime);
89
90 /* unnecessary
91 benchFunction(benchName + ": Reverse", units, function () {
92 for (var i = arrayToBenched.length; i > 0; i--) {
93 arrayFunction(arrayToBenched[i]);
94 }
95 }, hideTime);
96 */
97
98 benchFunction(benchName + ": Reverse short", units, function() {
99 for (var i = arrayToBenched.length; i--; ) {
100 arrayFunction(arrayToBenched[i]);
101 }
102 }, hideTime);
103
104 // duff's device loop unrolling variations
105 benchFunction(benchName + ": Duff's", units, function() {
106 var iLength = arrayToBenched.length;
107 var iter = Math.ceil(iLength / 8);
108 var start = iLength % 8;
109 var i = 0;
110 do {
111 switch (start) {
112 case 0: arrayFunction(arrayToBenched[i++]);
113 case 7: arrayFunction(arrayToBenched[i++]);
114 case 6: arrayFunction(arrayToBenched[i++]);
115 case 5: arrayFunction(arrayToBenched[i++]);
116 case 4: arrayFunction(arrayToBenched[i++]);
117 case 3: arrayFunction(arrayToBenched[i++]);
118 case 2: arrayFunction(arrayToBenched[i++]);
119 case 1: arrayFunction(arrayToBenched[i++]);
120 }
121 start = 0;
122 } while (--iter > 0);
123 }, hideTime);
124
125 benchFunction(benchName + ": Duff's modified", units, function() {
126 var iLength = arrayToBenched.length;
127 var iter = Math.ceil(iLength / 8);
128 var left = iLength % 8;
129 var i = 0;
130 if (left > 0) {
131 do {
132 arrayFunction(arrayToBenched[i++]);
133 } while (--left > 0);
134 }
135 do {
136 arrayFunction(arrayToBenched[i++]);
137 arrayFunction(arrayToBenched[i++]);
138 arrayFunction(arrayToBenched[i++]);
139 arrayFunction(arrayToBenched[i++]);
140 arrayFunction(arrayToBenched[i++]);
141 arrayFunction(arrayToBenched[i++]);
142 arrayFunction(arrayToBenched[i++]);
143 arrayFunction(arrayToBenched[i++]);
144 } while (--iter > 0);
145 }, hideTime);
146
147 benchFunction(benchName + ": for...in", units, function() {
148 for (var i in arrayToBenched) {
149 arrayFunction(arrayToBenched[i]);
150 }
151 }, hideTime);
152 },
153
154 BenchArrayLoop = function(arrayToBenched, benchName, testTimes, arrayFunction) {
155 TestArrayLoop(arrayToBenched, benchName, testTimes, arrayFunction, BenchFunction);
156 },
157
158 TimedBenchArrayLoop = function(arrayToBenched, benchName, timeToRunMs, arrayFunction) {
159 // from John Resig, higher is better
160 TestArrayLoop(arrayToBenched, benchName, timeToRunMs, arrayFunction, TimedBench, true);
161 };
162
163 // expose functions:
164 window.BenchLogWrite = BenchLogWrite;
165 window.BenchStart = BenchStart;
166 window.BenchEnd = BenchEnd;
167 window.BenchFunction = BenchFunction;
168 window.TimedBench = TimedBench;
169 window.FlushBenches = FlushBenches;
170 window.BenchArrayLoop = BenchArrayLoop;
171 window.TimedBenchArrayLoop = TimedBenchArrayLoop;
172
173})(window);