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 MylesBorins committed Jul 27, 2020
1 parent 39894f8 commit 74da2c4
Showing 1 changed file with 6 additions and 10 deletions.
16 changes: 6 additions & 10 deletions lib/internal/util/inspect.js
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 74da2c4

Please sign in to comment.