Skip to content

Commit ff87140

Browse files
committed
patch 8.2.2654: Vim9: getting a character from a string can be slow
Problem: Vim9: getting a character from a string can be slow. Solution: Avoid a function call to get the character byte size. (#8000)
1 parent 3a0f092 commit ff87140

2 files changed

Lines changed: 21 additions & 3 deletions

File tree

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,8 @@ static char *(features[]) =
750750

751751
static int included_patches[] =
752752
{ /* Add new patch number below this line */
753+
/**/
754+
2654,
753755
/**/
754756
2653,
755757
/**/

src/vim9execute.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,21 +1067,37 @@ char_from_string(char_u *str, varnumber_T index)
10671067
return NULL;
10681068
slen = STRLEN(str);
10691069

1070-
// do the same as for a list: a negative index counts from the end
1070+
// Do the same as for a list: a negative index counts from the end.
1071+
// Optimization to check the first byte to be below 0x80 (and no composing
1072+
// character follows) makes this a lot faster.
10711073
if (index < 0)
10721074
{
10731075
int clen = 0;
10741076

10751077
for (nbyte = 0; nbyte < slen; ++clen)
1076-
nbyte += mb_ptr2len(str + nbyte);
1078+
{
1079+
if (str[nbyte] < 0x80 && str[nbyte + 1] < 0x80)
1080+
++nbyte;
1081+
else if (enc_utf8)
1082+
nbyte += utfc_ptr2len(str + nbyte);
1083+
else
1084+
nbyte += mb_ptr2len(str + nbyte);
1085+
}
10771086
nchar = clen + index;
10781087
if (nchar < 0)
10791088
// unlike list: index out of range results in empty string
10801089
return NULL;
10811090
}
10821091

10831092
for (nbyte = 0; nchar > 0 && nbyte < slen; --nchar)
1084-
nbyte += mb_ptr2len(str + nbyte);
1093+
{
1094+
if (str[nbyte] < 0x80 && str[nbyte + 1] < 0x80)
1095+
++nbyte;
1096+
else if (enc_utf8)
1097+
nbyte += utfc_ptr2len(str + nbyte);
1098+
else
1099+
nbyte += mb_ptr2len(str + nbyte);
1100+
}
10851101
if (nbyte >= slen)
10861102
return NULL;
10871103
return vim_strnsave(str + nbyte, mb_ptr2len(str + nbyte));

0 commit comments

Comments
 (0)