From 7cd8128da3d81bdc8f6e9da19f09f236c1703800 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 30 Dec 2020 16:36:08 +0100 Subject: [PATCH] Improve JS performance by storing length before comparing to it in loops --- src/librustdoc/html/static/main.js | 98 ++++++++++----------- src/librustdoc/html/static/source-script.js | 8 +- 2 files changed, 50 insertions(+), 56 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index ec8024ffca5..3a13b7bceb1 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -648,8 +648,7 @@ function defocusSearchBar() { */ function execQuery(query, searchWords, filterCrates) { function itemTypeFromName(typename) { - var length = itemTypes.length; - for (var i = 0; i < length; ++i) { + for (var i = 0, len = itemTypes.length; i < len; ++i) { if (itemTypes[i] === typename) { return i; } @@ -667,8 +666,7 @@ function defocusSearchBar() { function transformResults(results, isType) { var out = []; - var length = results.length; - for (var i = 0; i < length; ++i) { + for (var i = 0, len = results.length; i < len; ++i) { if (results[i].id > -1) { var obj = searchIndex[results[i].id]; obj.lev = results[i].lev; @@ -697,11 +695,11 @@ function defocusSearchBar() { } } results = ar; - var i; - var nresults = results.length; - for (i = 0; i < nresults; ++i) { - results[i].word = searchWords[results[i].id]; - results[i].item = searchIndex[results[i].id] || {}; + var i, len, result; + for (i = 0, len = results.length; i < len; ++i) { + result = results[i]; + result.word = searchWords[result.id]; + result.item = searchIndex[result.id] || {}; } // if there are no results then return to default and fail if (results.length === 0) { @@ -775,8 +773,7 @@ function defocusSearchBar() { return 0; }); - var length = results.length; - for (i = 0; i < length; ++i) { + for (i = 0, len = results.length; i < len; ++i) { var result = results[i]; // this validation does not make sense when searching by types @@ -833,11 +830,10 @@ function defocusSearchBar() { var vlength = val.generics.length; for (var y = 0; y < vlength; ++y) { var lev = { pos: -1, lev: MAX_LEV_DISTANCE + 1}; - var elength = elems.length; var firstGeneric = getObjectFromId(val.generics[y]).name; - for (var x = 0; x < elength; ++x) { + for (var x = 0, elength = elems.length; x < elength; ++x) { var tmp_lev = levenshtein(getObjectFromId(elems[x]).name, - firstGeneric); + firstGeneric); if (tmp_lev < lev.lev) { lev.lev = tmp_lev; lev.pos = x; @@ -861,7 +857,7 @@ function defocusSearchBar() { // Check for type name and type generics (if any). function checkType(obj, val, literalSearch) { var lev_distance = MAX_LEV_DISTANCE + 1; - var x; + var len, x, y, e_len, firstGeneric; if (obj[NAME] === val.name) { if (literalSearch === true) { if (val.generics && val.generics.length !== 0) { @@ -870,10 +866,12 @@ function defocusSearchBar() { var elems = obj[GENERICS_DATA].slice(0); var allFound = true; - for (var y = 0; allFound === true && y < val.generics.length; ++y) { + len = val.generics.length; + for (y = 0; allFound === true && y < len; ++y) { allFound = false; - var firstGeneric = getObjectFromId(val.generics[y]).name; - for (x = 0; allFound === false && x < elems.length; ++x) { + firstGeneric = getObjectFromId(val.generics[y]).name; + e_len = elems.length; + for (x = 0; allFound === false && x < e_len; ++x) { allFound = getObjectFromId(elems[x]).name === firstGeneric; } if (allFound === true) { @@ -903,12 +901,10 @@ function defocusSearchBar() { // Names didn't match so let's check if one of the generic types could. if (literalSearch === true) { if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) { - var length = obj[GENERICS_DATA].length; - for (x = 0; x < length; ++x) { - if (obj[GENERICS_DATA][x] === val.name) { - return true; - } - } + return onEach(obj[GENERICS_DATA], + function(name) { + return name === val.name; + }); } return false; } @@ -965,7 +961,7 @@ function defocusSearchBar() { if (typeof ret[0] === "string") { ret = [ret]; } - for (var x = 0; x < ret.length; ++x) { + for (var x = 0, len = ret.length; x < len; ++x) { var tmp = ret[x]; if (typePassesFilter(typeFilter, tmp[1]) === false) { continue; @@ -1072,23 +1068,22 @@ function defocusSearchBar() { // aliases to be before the others in the displayed results. var aliases = []; var crateAliases = []; - var i; if (filterCrates !== undefined) { if (ALIASES[filterCrates] && ALIASES[filterCrates][query.search]) { - for (i = 0; i < ALIASES[filterCrates][query.search].length; ++i) { - aliases.push( - createAliasFromItem( - searchIndex[ALIASES[filterCrates][query.search][i]])); + var query_aliases = ALIASES[filterCrates][query.search]; + var len = query_aliases.length; + for (var i = 0; i < len; ++i) { + aliases.push(createAliasFromItem(searchIndex[query_aliases[i]])); } } } else { Object.keys(ALIASES).forEach(function(crate) { if (ALIASES[crate][query.search]) { var pushTo = crate === window.currentCrate ? crateAliases : aliases; - for (i = 0; i < ALIASES[crate][query.search].length; ++i) { - pushTo.push( - createAliasFromItem( - searchIndex[ALIASES[crate][query.search][i]])); + var query_aliases = ALIASES[crate][query.search]; + var len = query_aliases.length; + for (var i = 0; i < len; ++i) { + pushTo.push(createAliasFromItem(searchIndex[query_aliases[i]])); } } }); @@ -1123,11 +1118,12 @@ function defocusSearchBar() { // quoted values mean literal search var nSearchWords = searchWords.length; - var i; + var i, it; var ty; var fullId; var returned; var in_args; + var len; if ((val.charAt(0) === "\"" || val.charAt(0) === "'") && val.charAt(val.length - 1) === val.charAt(0)) { @@ -1175,7 +1171,7 @@ function defocusSearchBar() { var input = parts[0]; // sort inputs so that order does not matter var inputs = input.split(",").map(trimmer).sort(); - for (i = 0; i < inputs.length; ++i) { + for (i = 0, len = inputs.length; i < len; ++i) { inputs[i] = extractGenerics(inputs[i]); } var output = extractGenerics(parts[1]); @@ -1200,7 +1196,7 @@ function defocusSearchBar() { is_module = true; } else { var allFound = true; - for (var it = 0; allFound === true && it < inputs.length; it++) { + for (it = 0, len = inputs.length; allFound === true && it < len; it++) { allFound = checkType(type, inputs[it], true); } in_args = allFound; @@ -1243,7 +1239,7 @@ function defocusSearchBar() { var paths = valLower.split("::"); var j; - for (j = 0; j < paths.length; ++j) { + for (j = 0, len = paths.length; j < len; ++j) { if (paths[j] === "") { paths.splice(j, 1); j -= 1; @@ -1365,7 +1361,7 @@ function defocusSearchBar() { * @return {[boolean]} [Whether the result is valid or not] */ function validateResult(name, path, keys, parent) { - for (var i = 0; i < keys.length; ++i) { + for (var i = 0, len = keys.length; i < len; ++i) { // each check is for validation so we negate the conditions and invalidate if (!( // check for an exact name match @@ -1686,7 +1682,7 @@ function defocusSearchBar() { function getSmallest(arrays, positions, notDuplicates) { var start = null; - for (var it = 0; it < positions.length; ++it) { + for (var it = 0, len = positions.length; it < len; ++it) { if (arrays[it].length > positions[it] && (start === null || start > arrays[it][positions[it]].lev) && !notDuplicates[arrays[it][positions[it]].fullPath]) { @@ -1701,7 +1697,7 @@ function defocusSearchBar() { var positions = []; var notDuplicates = {}; - for (var x = 0; x < arrays.length; ++x) { + for (var x = 0, arrays_len = arrays.length; x < arrays_len; ++x) { positions.push(0); } while (ret.length < MAX_RESULTS) { @@ -1710,7 +1706,7 @@ function defocusSearchBar() { if (smallest === null) { break; } - for (x = 0; x < arrays.length && ret.length < MAX_RESULTS; ++x) { + for (x = 0; x < arrays_len && ret.length < MAX_RESULTS; ++x) { if (arrays[x].length > positions[x] && arrays[x][positions[x]].lev === smallest && !notDuplicates[arrays[x][positions[x]].fullPath]) { @@ -1730,7 +1726,7 @@ function defocusSearchBar() { "others": [], }; - for (var i = 0; i < queries.length; ++i) { + for (var i = 0, len = queries.length; i < len; ++i) { query = queries[i].trim(); if (query.length !== 0) { var tmp = execQuery(getQuery(query), searchWords, filterCrates); @@ -1884,7 +1880,7 @@ function defocusSearchBar() { ALIASES[crate][alias_name] = []; } local_aliases = aliases[alias_name]; - for (j = 0; j < local_aliases.length; ++j) { + for (j = 0, len = local_aliases.length; j < len; ++j) { ALIASES[crate][alias_name].push(local_aliases[j] + currentIndex); } } @@ -2052,8 +2048,7 @@ function defocusSearchBar() { div.appendChild(h3); var ul = document.createElement("ul"); - var length = filtered.length; - for (var i = 0; i < length; ++i) { + for (var i = 0, len = filtered.length; i < len; ++i) { var item = filtered[i]; var name = item[0]; var desc = item[1]; // can be null @@ -2122,21 +2117,18 @@ function defocusSearchBar() { } var libs = Object.getOwnPropertyNames(imp); - var llength = libs.length; - for (var i = 0; i < llength; ++i) { + for (var i = 0, llength = libs.length; i < llength; ++i) { if (libs[i] === currentCrate) { continue; } var structs = imp[libs[i]]; - var slength = structs.length; struct_loop: - for (var j = 0; j < slength; ++j) { + for (var j = 0, slength = structs.length; j < slength; ++j) { var struct = structs[j]; var list = struct.synthetic ? synthetic_implementors : implementors; if (struct.synthetic) { - var stlength = struct.types.length; - for (var k = 0; k < stlength; k++) { + for (var k = 0, stlength = struct.types.length; k < stlength; k++) { if (inlined_types.has(struct.types[k])) { continue struct_loop; } @@ -2853,7 +2845,7 @@ function defocusSearchBar() { return 0; }); var savedCrate = getSettingValue("saved-filter-crate"); - for (var i = 0; i < crates_text.length; ++i) { + for (var i = 0, len = crates_text.length; i < len; ++i) { var option = document.createElement("option"); option.value = crates_text[i]; option.innerText = crates_text[i]; diff --git a/src/librustdoc/html/static/source-script.js b/src/librustdoc/html/static/source-script.js index 6805f2a266f..a9cc0ffdf79 100644 --- a/src/librustdoc/html/static/source-script.js +++ b/src/librustdoc/html/static/source-script.js @@ -8,7 +8,7 @@ function getCurrentFilePath() { var parts = window.location.pathname.split("/"); var rootPathParts = window.rootPath.split("/"); - for (var i = 0; i < rootPathParts.length; ++i) { + for (var i = 0, len = rootPathParts.length; i < len; ++i) { if (rootPathParts[i] === "..") { parts.pop(); } @@ -35,12 +35,14 @@ function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) { }; name.innerText = elem["name"]; + var i, len; + var children = document.createElement("div"); children.className = "children"; var folders = document.createElement("div"); folders.className = "folders"; if (elem.dirs) { - for (var i = 0; i < elem.dirs.length; ++i) { + for (i = 0, len = elem.dirs.length; i < len; ++i) { if (createDirEntry(elem.dirs[i], folders, fullPath, currentFile, hasFoundFile) === true) { addClass(name, "expand"); @@ -53,7 +55,7 @@ function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) { var files = document.createElement("div"); files.className = "files"; if (elem.files) { - for (i = 0; i < elem.files.length; ++i) { + for (i = 0, len = elem.files.length; i < len; ++i) { var file = document.createElement("a"); file.innerText = elem.files[i]; file.href = window.rootPath + "src/" + fullPath + elem.files[i] + ".html";