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 <[email protected]>

PR-URL: #33674
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Tobias Nießen <[email protected]>
Reviewed-By: Anto Aravinth <[email protected]>
  • Loading branch information
BridgeAR authored and addaleax committed Jul 20, 2020
1 parent 77b68f9 commit 2e82982
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 @@ -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)
Expand All @@ -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;
Expand All @@ -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)) {
Expand Down

0 comments on commit 2e82982

Please sign in to comment.