From 74da2c44ca5a0c02ef7567118be152b7f432ac0e Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Sun, 31 May 2020 18:23:07 +0200 Subject: [PATCH] util: improve getStringWidth performance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes sure the common path does not normalize the input string. It's only required for characters that are outside of the ASCII range. Signed-off-by: Ruben Bridgewater PR-URL: https://github.com/nodejs/node/pull/33674 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Tobias Nießen Reviewed-By: Anto Aravinth --- lib/internal/util/inspect.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 824c5961e9512c..495271fa62eecb 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -1995,13 +1995,6 @@ function formatWithOptionsInternal(inspectOptions, ...args) { return str; } -function prepareStringForGetStringWidth(str, removeControlChars) { - str = str.normalize('NFC'); - if (removeControlChars) - str = stripVTControlCharacters(str); - return str; -} - if (internalBinding('config').hasIntl) { const icu = internalBinding('icu'); // icu.getStringWidth(string, ambiguousAsFullWidth, expandEmojiSequence) @@ -2012,13 +2005,14 @@ if (internalBinding('config').hasIntl) { getStringWidth = function getStringWidth(str, removeControlChars = true) { let width = 0; - str = prepareStringForGetStringWidth(str, removeControlChars); + if (removeControlChars) + str = stripVTControlCharacters(str); for (let i = 0; i < str.length; i++) { // Try to avoid calling into C++ by first handling the ASCII portion of // the string. If it is fully ASCII, we skip the C++ part. const code = str.charCodeAt(i); if (code >= 127) { - width += icu.getStringWidth(str.slice(i)); + width += icu.getStringWidth(str.slice(i).normalize('NFC')); break; } width += code >= 32 ? 1 : 0; @@ -2032,7 +2026,9 @@ if (internalBinding('config').hasIntl) { getStringWidth = function getStringWidth(str, removeControlChars = true) { let width = 0; - str = prepareStringForGetStringWidth(str, removeControlChars); + if (removeControlChars) + str = stripVTControlCharacters(str); + str = str.normalize('NFC'); for (const char of str) { const code = char.codePointAt(0); if (isFullWidthCodePoint(code)) {