require(["../external/benchmark/benchmark", "../external/requirejs-domready/domReady!", "../external/requirejs-text/text!selectors.css"] , function (Benchmark, document, selectors){ "use strict"; selectors = (function (){ var s = selectors.split("\n"), i = 0; for (; i < _AN_Read_length("length", s); i++ ){ if (!s[i]) { s.splice(i-- , 1); } } return s; } )(); var profiling, trim, rtrim = /\S/.test("\xA0")? (/^[\s\xA0]+|[\s\xA0]+$/g): /^\s+|\s+$/g, rspaces = /\s+/, ptrim = String.prototype.trim, testHtml = "selector", urlParams = (function (){ var parts, value, paramValue, params = { } , search = _AN_Read_search("search", _AN_Read_location("location", window)).substring(1).split("&"), i = 0, len = _AN_Read_length("length", search); for (; i < len; i++ ){ parts = search[i].split("="); value = parts[1]; if (!value || value === "true") { paramValue = true ; } else { paramValue = value === "false"? false : decodeURIComponent(value); } params[decodeURIComponent(parts[0])] = paramValue; } return params; } )(), useQSA = urlParams.qsa || false , maxTime = 0.5, minSamples = 3, iframes = { } , errors = { } , engines = { "jquery-1.7.2/jquery": "jQuery.find( s, d )", "sizzle-old/sizzle": "Sizzle( s, d )", "sizzle": "Sizzle( s, d )", "mootools-slick/slick": "Slick.search( d, s )", "nwmatcher/nwmatcher": "NW.Dom.select( s, d )"} , scores = (function (){ var engine, scores = { } ; for (engine in engines){ scores[engine] = 0; } return scores; } )(), returned = (function (){ var engine, returned = { } ; for (engine in engines){ returned[engine] = { } ; } return returned; } )(), numEngines = (function (){ var engine, count = 0; for (engine in engines){ count++ ; } return count; } )(), selectorIndex = 0; window.iframeCallbacks = { } ; trim = ptrim? function (str){ return ptrim.call(str); } : function (str){ return _AN_Call_replace("replace", str, rtrim, ""); } ; function get(id){ return document.getElementById(id); } function addClass(elem, classStr){ classStr = classStr.split(rspaces); var c, cls = " " + elem.className + " ", i = 0, len = _AN_Read_length("length", classStr); for (; i < len; ++i){ c = classStr[i]; if (c && cls.indexOf(" " + c + " ") < 0) { cls += c + " "; } } elem.className = trim(cls); } function removeClass(elem, classStr){ var cls, len, i; if (classStr !== undefined) { classStr = classStr.split(rspaces); cls = " " + elem.className + " "; i = 0; len = _AN_Read_length("length", classStr); for (; i < len; ++i){ cls = _AN_Call_replace("replace", cls, " " + classStr[i] + " ", " "); } cls = trim(cls); } else { cls = ""; } if (elem.className !== cls) { elem.className = cls; } } function profile(name){ if (window.console && typeof console.profile !== "undefined" && !profiling) { profiling = true ; console.profile(name); } } function profileEnd(name){ if (profiling) { profiling = false ; console.profileEnd(name); } } function firstTestedColumn(){ return selectorIndex * (numEngines + 1) + 1; } function url(value){ return value + (/\?/.test(value)? "&": "?") + new Date().getTime() + "" + parseInt(Math.random() * 100000, 10); } function getHz(bench){ return 1 / (bench.stats.mean + bench.stats.moe); } function getCommonReturn(selector){ var engine, count, common, max = 0, counts = { } ; for (engine in returned){ count = returned[engine][selector]; if (count) { count = _AN_Read_length("length", count); counts[count] = (counts[count] || 0) + 1; } } for (count in counts){ if (counts[count] > max) { max = counts[count]; common = count; } } return + common; } function buildTable(){ var engine, i = 0, len = _AN_Read_length("length", selectors), headers = "selectors", emptyColumns = "", rows = ""; for (engine in engines){ headers += "" + engine.match(/^[^/]+/)[0] + ""; emptyColumns += " "; } for (; i < len; i++ ){ rows += "" + selectors[i] + "" + emptyColumns + ""; } rows += "Total (more is better)" + emptyColumns + ""; _AN_Write_innerhtml("innerHTML", get("perf-table-headers"), false , headers); _AN_Write_innerhtml("innerHTML", get("perf-table-body"), false , rows); } function createIframe(engine, suite, callbackIndex){ var src = url("./data/" + testHtml + ".html?engine=" + encodeURIComponent(engine) + "&suite=" + encodeURIComponent(suite) + "&callback=" + callbackIndex + "&qsa=" + useQSA), iframe = _AN_Call_createelement("createElement", document, "iframe"); _AN_Call_setattribute("setAttribute", iframe, "src", src); _AN_Write_csstext("cssText", iframe.style, false , "width: 500px; height: 500px; position: absolute; " + "top: -600px; left: -600px; visibility: hidden;"); _AN_Call_appendchild("appendChild", document.body, iframe); iframes[suite].push(iframe); return iframe; } function addTestToSuite(suite, selector, engine, iframeLoaded){ function test(document){ var win = this, select = new Function("w", "s", "d", "return " + (engine !== "qsa"? "w.": "") + engines[engine]); suite.add(engine, function (){ returned[engine][selector] = select(win, selector, document); } ); if (typeof iframeLoaded !== "undefined") { iframeLoaded(); } } var index, name = suite.name, callbacks = window.iframeCallbacks[name]; index = callbacks.push(function (){ var self = this, args = arguments; _AN_Call_settimeout("setTimeout", window, function (){ test.apply(self, args); } , 0); } ) - 1; createIframe(engine, name, index); } function testSelector(selector){ var engine, suite = Benchmark.Suite(selector), name = suite.name, count = numEngines; function loaded(){ if (--count === 0) { suite.run(); } } window.iframeCallbacks[name] = [] ; iframes[name] = [] ; for (engine in engines){ addTestToSuite(suite, selector, engine, loaded); } } function onError(){ errors[this.id] = true ; this.abort(); return false ; } function onStart(){ profile(selectors[selectorIndex]); var selectorElem = get("selector" + selectorIndex); addClass(selectorElem, "pending"); } function onCycle(event){ var i = firstTestedColumn(), len = i + numEngines, tableBody = get("perf-table-body"), tds = _AN_Call_getelementsbytagname("getElementsByTagName", tableBody, "td"), bench = _AN_Read_target("target", event), hasError = errors[bench.id], textNode = document.createTextNode(hasError? "FAILED": Benchmark.formatNumber(getHz(bench).toFixed(2)) + "o/s | " + _AN_Read_length("length", returned[bench.name][selectors[selectorIndex]]) + " found"); for (; i < len; i++ ){ if (_AN_Call_getattribute("getAttribute", tds[i], "data-engine") === bench.name) { _AN_Call_appendchild("appendChild", tds[i], textNode); if (hasError) { addClass(tds[i], "black"); } break ; } } } function onComplete(){ profileEnd(selectors[selectorIndex]); var fastestHz, slowestHz, elem, attr, j, jlen, td, ret, i = firstTestedColumn(), selector = selectors[selectorIndex], common = getCommonReturn(selector), len = i + numEngines, selectorElem = get("selector" + selectorIndex), tableBody = get("perf-table-body"), tds = _AN_Call_getelementsbytagname("getElementsByTagName", tableBody, "td"), fastest = this.filter("fastest"), slowest = this.filter("slowest"); removeClass(selectorElem, "pending"); this.forEach(function (bench){ if (errors[bench.id]) { delete errors[bench.id]; } else { scores[bench.name] += getHz(bench); } } ); for (; i < len; i++ ){ td = tds[i]; attr = _AN_Call_getattribute("getAttribute", td, "data-engine"); ret = returned[attr][selector]; if (ret && _AN_Read_length("length", ret) !== common) { addClass(td, "yellow"); continue ; } for (j = 0, jlen = _AN_Read_length("length", slowest); j < jlen; j++ ){ if (slowest[j].name === attr) { addClass(td, "red"); } } for (j = 0, jlen = _AN_Read_length("length", fastest); j < jlen; j++ ){ if (fastest[j].name === attr) { addClass(td, "green"); } } } for (i = 0, len = _AN_Read_length("length", iframes[this.name]); i < len; i++ ){ document.body.removeChild(iframes[this.name].pop()); } delete iframes[this.name]; window.iframeCallbacks[this.name] = null ; try { delete window.iframeCallbacks[this.name]; } catch (e) { } if (++selectorIndex < _AN_Read_length("length", selectors)) { testSelector(selectors[selectorIndex]); } else { addClass(document.body, "complete"); slowest = fastest = undefined; fastestHz = 0; slowestHz = Infinity; for (i in scores){ if (scores[i] > fastestHz) { fastestHz = scores[i]; fastest = i; } else if (scores[i] < slowestHz) { slowestHz = scores[i]; slowest = i; } scores[i] = Benchmark.formatNumber(scores[i].toFixed(2)) + "o/s"; } elem = _AN_Call_createelement("createElement", document, "h3"); _AN_Write_innerhtml("innerHTML", elem, false , "The fastest is " + fastest + " (" + scores[fastest] + "). " + "The slowest is " + slowest + " (" + scores[slowest] + ")."); _AN_Call_appendchild("appendChild", get("header"), elem); i = firstTestedColumn(); while ((elem = tds[i++ ])){ attr = _AN_Call_getattribute("getAttribute", elem, "data-engine"); if (attr === fastest) { addClass(elem, "green"); } else if (attr === slowest) { addClass(elem, "red"); } _AN_Call_appendchild("appendChild", elem, document.createTextNode(scores[attr])); } } } Benchmark.options.async = true ; Benchmark.options.maxTime = maxTime; Benchmark.options.minSamples = minSamples; Benchmark.options.onError = onError; Benchmark.Suite.options.onStart = onStart; Benchmark.Suite.options.onCycle = onCycle; Benchmark.Suite.options.onComplete = onComplete; buildTable(); testSelector(selectors[selectorIndex]); } );