Skip to content

Commit

Permalink
util: improve getStringWidth performance
Browse files Browse the repository at this point in the history
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 <ruben@bridgewater.de>

PR-URL: #33674
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com>
  • Loading branch information
BridgeAR authored and addaleax committed Sep 22, 2020
1 parent 39dea8f commit 58cd76c
Showing 1 changed file with 6 additions and 10 deletions.
16 changes: 6 additions & 10 deletions lib/internal/util/inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -1953,13 +1953,6 @@ function formatWithOptions(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)
Expand All @@ -1970,13 +1963,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;
Expand All @@ -1990,7 +1984,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)) {
Expand Down

0 comments on commit 58cd76c

Please sign in to comment.