0
0
mirror of https://github.com/vim/vim.git synced 2025-09-27 04:14:06 -04:00

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)
This commit is contained in:
Bram Moolenaar
2021-03-26 13:34:05 +01:00
parent 3a0f092ac0
commit ff87140046
2 changed files with 21 additions and 3 deletions

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
2654,
/**/ /**/
2653, 2653,
/**/ /**/

View File

@@ -1067,13 +1067,22 @@ char_from_string(char_u *str, varnumber_T index)
return NULL; return NULL;
slen = STRLEN(str); slen = STRLEN(str);
// do the same as for a list: a negative index counts from the end // Do the same as for a list: a negative index counts from the end.
// Optimization to check the first byte to be below 0x80 (and no composing
// character follows) makes this a lot faster.
if (index < 0) if (index < 0)
{ {
int clen = 0; int clen = 0;
for (nbyte = 0; nbyte < slen; ++clen) for (nbyte = 0; nbyte < slen; ++clen)
nbyte += mb_ptr2len(str + nbyte); {
if (str[nbyte] < 0x80 && str[nbyte + 1] < 0x80)
++nbyte;
else if (enc_utf8)
nbyte += utfc_ptr2len(str + nbyte);
else
nbyte += mb_ptr2len(str + nbyte);
}
nchar = clen + index; nchar = clen + index;
if (nchar < 0) if (nchar < 0)
// unlike list: index out of range results in empty string // unlike list: index out of range results in empty string
@@ -1081,7 +1090,14 @@ char_from_string(char_u *str, varnumber_T index)
} }
for (nbyte = 0; nchar > 0 && nbyte < slen; --nchar) for (nbyte = 0; nchar > 0 && nbyte < slen; --nchar)
nbyte += mb_ptr2len(str + nbyte); {
if (str[nbyte] < 0x80 && str[nbyte + 1] < 0x80)
++nbyte;
else if (enc_utf8)
nbyte += utfc_ptr2len(str + nbyte);
else
nbyte += mb_ptr2len(str + nbyte);
}
if (nbyte >= slen) if (nbyte >= slen)
return NULL; return NULL;
return vim_strnsave(str + nbyte, mb_ptr2len(str + nbyte)); return vim_strnsave(str + nbyte, mb_ptr2len(str + nbyte));