Created
August 20, 2009 15:46
-
-
Save dieseltravis/171149 to your computer and use it in GitHub Desktop.
Benchmarking JS with and without Firebug's console
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function (w) { | |
| var console = w.console, | |
| BenchLog = "", | |
| Bench = {}, | |
| BenchLogWrite = function (message) { | |
| if (console && console.log) { | |
| console.log(message); | |
| } else { // no console logger | |
| BenchLog += message; | |
| } | |
| }, | |
| BenchStart = function (benchName) { | |
| if (console && console.time) { | |
| console.time(benchName); | |
| } else { // no console timer | |
| Bench[benchName] = w.performance.now(); | |
| } | |
| }, | |
| BenchEnd = function (benchName) { | |
| if (console && console.time) { | |
| console.timeEnd(benchName); | |
| } else { // no console timer | |
| Bench[benchName + "End"] = w.performance.now(); | |
| BenchLog += benchName + ":\t" + (Bench[benchName + "End"] - Bench[benchName]) + "ms\n"; | |
| } | |
| }, | |
| BenchFunction = function (benchName, testTimes, benchFunction) { | |
| // lower is better | |
| BenchStart(benchName); | |
| for (var i = testTimes; i--; ) { | |
| benchFunction(); | |
| } | |
| BenchEnd(benchName); | |
| }, | |
| TimedBench = function (benchName, timeToRunMs, benchFunction, hideTime) { | |
| // from John Resig, higher is better | |
| var start = w.performance.now(); | |
| var time = 0; | |
| var score = 0; | |
| while (time < timeToRunMs) { | |
| benchFunction (); | |
| time = w.performance.now() - start; | |
| score++; | |
| } | |
| var status; | |
| if (hideTime) { | |
| status = benchName + ":\t" + score + "\n"; | |
| } else { | |
| status = benchName + ":\tscore for " + timeToRunMs + "ms:\t" + score + "\n"; | |
| } | |
| BenchLogWrite(status); | |
| }, | |
| FlushBenches = function () { | |
| if (!(console && console.time && console.log) && BenchLog && (BenchLog.length > 0)) { | |
| w.alert(BenchLog); | |
| BenchLog = ""; | |
| } | |
| }, | |
| // loop functions for determining the fastest way to enumerate an array | |
| TestArrayLoop = function (arrayToBenched, benchName, units, arrayFunction, benchFunction, hideTime) { | |
| // try various loops on array, variations from Steve Souders | |
| // NOTE: don't modify arrayToBench in arrayfunction (arrayToBench[i]) - it would be "bad" | |
| if (hideTime) { | |
| BenchLogWrite(benchName + " (score for " + units + "ms):\n"); | |
| } else { | |
| BenchLogWrite(benchName + ":\n"); | |
| } | |
| benchFunction(benchName + ": Standard", units, function () { | |
| for (var i = 0; i < arrayToBenched.length; i++) { | |
| arrayFunction(arrayToBenched[i]); | |
| } | |
| }, hideTime); | |
| benchFunction(benchName + ": length var", units, function () { | |
| for (var i = 0, iLength = arrayToBenched.length; i < iLength; i++) { | |
| arrayFunction(arrayToBenched[i]); | |
| } | |
| }, hideTime); | |
| /* unnecessary | |
| benchfunction (benchName + ": Reverse", units, function () { | |
| for (var i = arrayToBenched.length; i > 0; i--) { | |
| arrayfunction (arrayToBenched[i]); | |
| } | |
| }, hideTime); | |
| */ | |
| benchFunction(benchName + ": Reverse short", units, function () { | |
| for (var i = arrayToBenched.length; i--; ) { | |
| arrayFunction(arrayToBenched[i]); | |
| } | |
| }, hideTime); | |
| // duff's device loop unrolling variations | |
| benchFunction(benchName + ": Duff's", units, function () { | |
| var iLength = arrayToBenched.length; | |
| var iter = Math.ceil(iLength / 8); | |
| var start = iLength % 8; | |
| var i = 0; | |
| do { | |
| switch (start) { | |
| case 0: arrayFunction(arrayToBenched[i++]); | |
| case 7: arrayFunction(arrayToBenched[i++]); | |
| case 6: arrayFunction(arrayToBenched[i++]); | |
| case 5: arrayFunction(arrayToBenched[i++]); | |
| case 4: arrayFunction(arrayToBenched[i++]); | |
| case 3: arrayFunction(arrayToBenched[i++]); | |
| case 2: arrayFunction(arrayToBenched[i++]); | |
| case 1: arrayFunction(arrayToBenched[i++]); | |
| } | |
| start = 0; | |
| } while (--iter > 0); | |
| }, hideTime); | |
| benchFunction(benchName + ": Duff's modified", units, function () { | |
| var iLength = arrayToBenched.length; | |
| var iter = Math.ceil(iLength / 8); | |
| var left = iLength % 8; | |
| var i = 0; | |
| if (left > 0) { | |
| do { | |
| arrayFunction(arrayToBenched[i++]); | |
| } while (--left > 0); | |
| } | |
| do { | |
| arrayFunction(arrayToBenched[i++]); | |
| arrayFunction(arrayToBenched[i++]); | |
| arrayFunction(arrayToBenched[i++]); | |
| arrayFunction(arrayToBenched[i++]); | |
| arrayFunction(arrayToBenched[i++]); | |
| arrayFunction(arrayToBenched[i++]); | |
| arrayFunction(arrayToBenched[i++]); | |
| arrayFunction(arrayToBenched[i++]); | |
| } while (--iter > 0); | |
| }, hideTime); | |
| benchFunction(benchName + ": for...in", units, function () { | |
| for (var i in arrayToBenched) { | |
| arrayFunction(arrayToBenched[i]); | |
| } | |
| }, hideTime); | |
| }, | |
| BenchArrayLoop = function (arrayToBenched, benchName, testTimes, arrayFunction) { | |
| TestArrayLoop(arrayToBenched, benchName, testTimes, arrayFunction, BenchFunction); | |
| }, | |
| TimedBenchArrayLoop = function (arrayToBenched, benchName, timeToRunMs, arrayFunction) { | |
| // from John Resig, higher is better | |
| TestArrayLoop(arrayToBenched, benchName, timeToRunMs, arrayFunction, TimedBench, true); | |
| }; | |
| // thx http://gent.ilcore.com/2012/06/better-timer-for-javascript.html | |
| w.performance = w.performance || {}; | |
| performance.now = (function () { | |
| return performance.now || | |
| performance.mozNow || | |
| performance.msNow || | |
| performance.oNow || | |
| performance.webkitNow || | |
| function() { return new Date().getTime(); }; | |
| })(); | |
| // expose functions: | |
| w.BenchLogWrite = BenchLogWrite; | |
| w.BenchStart = BenchStart; | |
| w.BenchEnd = BenchEnd; | |
| w.BenchFunction = BenchFunction; | |
| w.TimedBench = TimedBench; | |
| w.FlushBenches = FlushBenches; | |
| w.BenchArrayLoop = BenchArrayLoop; | |
| w.TimedBenchArrayLoop = TimedBenchArrayLoop; | |
| })(window); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // sample USAGE: (see http://jsbin.com/ogike/4 & http://jsbin.com/ehawud/6 for demos) | |
| // adjust iteration count depending on length of task | |
| var testTimes = 1000; | |
| BenchFunction("trial1", testTimes, function () { | |
| $(".captionWrapper > .inlineWrapOuter > .inlineWrap > img"); | |
| }); | |
| BenchFunction("trial2", testTimes, function () { | |
| $(".captionWrapper img"); | |
| }); | |
| FlushBenches(); | |
| /* results are output to Firebug's console if it's available, otherwise it alerts them | |
| On the example above I get the following: | |
| Firefox w/o Firebug will alert: | |
| trial1: 61ms | |
| trial2: 57ms | |
| Firefox w/ Firebug console: | |
| trial1: 66ms | |
| trial2: 63ms | |
| IE6 will alert: | |
| trial1: 672ms | |
| trial2: 2094ms | |
| In this specific case any minute perf gains in Firefox are canceled out by IE6 sucking. | |
| */ | |
| // timed bench example | |
| var testLengthMs = 1000; | |
| TimedBench("trial3", testLengthMs, function () { | |
| $(".captionWrapper > .inlineWrapOuter > .inlineWrap > img"); | |
| }); | |
| TimedBench("trial4", testLengthMs, function () { | |
| $(".captionWrapper img"); | |
| }); | |
| FlushBenches(); | |
| /* results: (with jQuery 1.4.2) | |
| Firefox 3.6: | |
| trial3: score for 1000ms: 18942 | |
| trial4: score for 1000ms: 20828 | |
| IE 8.0.6001.18882: | |
| trial3: score for 1000ms: 10085 | |
| trial4: score for 1000ms: 10723 | |
| IE 8.0.6001.18882 64-bit: | |
| trial3: score for 1000ms: 10081 | |
| trial4: score for 1000ms: 11212 | |
| Chrome 4.0.249.89 unknown (38071): | |
| trial3: score for 1000ms: 34148 | |
| trial4: score for 1000ms: 36843 | |
| Safari 4.0.4 (531.21.10): | |
| trial3: score for 1000ms: 39166 | |
| trial4: score for 1000ms: 43815 | |
| Opera 10.10: | |
| trial3: score for 1000ms: 22655 | |
| trial4: score for 1000ms: 27130 | |
| */ | |
| // array-loop example | |
| var iconArray = []; | |
| // *snip* add a bunch of items to array | |
| BenchArrayLoop(iconArray, "iconArray", 10000, function (arrayItem) { | |
| var x = arrayItem; | |
| }); | |
| FlushBenches(); | |
| /* results: | |
| Firefox: | |
| iconArray: Standard: 310ms | |
| iconArray: length var: 287ms | |
| iconArray: Reverse: 145ms | |
| iconArray: Reverse short: 124ms | |
| iconArray: Duff's: 189ms | |
| iconArray: Duff's modified: 252ms | |
| IE6: | |
| iconArray: Standard: 1078ms | |
| iconArray: length var: 734ms | |
| iconArray: Reverse: 750ms | |
| iconArray: Reverse short: 578ms | |
| iconArray: Duff's: 688ms | |
| iconArray: Duff's modified: 593ms | |
| */ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment