From 9d1b8fc60cc31f12618e58c10a2669506b7ce9bf Mon Sep 17 00:00:00 2001 From: Francesco Trotta Date: Tue, 11 Apr 2023 23:44:39 +0200 Subject: [PATCH] perf: Binary search in token store `utils.search` (#17066) * perf: Binary search in token store `utils.search` * Use `Math.trunc` * Switch back to `| 0`, inline `getStartLocation` --- lib/source-code/token-store/utils.js | 37 ++++++++++++++++------------ 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/lib/source-code/token-store/utils.js b/lib/source-code/token-store/utils.js index 859831916ea..3e01470321a 100644 --- a/lib/source-code/token-store/utils.js +++ b/lib/source-code/token-store/utils.js @@ -4,20 +4,6 @@ */ "use strict"; -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Gets `token.range[0]` from the given token. - * @param {Node|Token|Comment} token The token to get. - * @returns {number} The start location. - * @private - */ -function getStartLocation(token) { - return token.range[0]; -} - //------------------------------------------------------------------------------ // Exports //------------------------------------------------------------------------------ @@ -30,9 +16,28 @@ function getStartLocation(token) { * @returns {number} The found index or `tokens.length`. */ exports.search = function search(tokens, location) { - const index = tokens.findIndex(el => location <= getStartLocation(el)); + for (let minIndex = 0, maxIndex = tokens.length - 1; minIndex <= maxIndex;) { - return index === -1 ? tokens.length : index; + /* + * Calculate the index in the middle between minIndex and maxIndex. + * `| 0` is used to round a fractional value down to the nearest integer: this is similar to + * using `Math.trunc()` or `Math.floor()`, but performance tests have shown this method to + * be faster. + */ + const index = (minIndex + maxIndex) / 2 | 0; + const token = tokens[index]; + const tokenStartLocation = token.range[0]; + + if (location <= tokenStartLocation) { + if (index === minIndex) { + return index; + } + maxIndex = index; + } else { + minIndex = index + 1; + } + } + return tokens.length; }; /**