From: Bram Moolenaar Date: Fri, 26 Mar 2021 12:34:05 +0000 (+0100) Subject: patch 8.2.2654: Vim9: getting a character from a string can be slow X-Git-Tag: v8.2.2654 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ff871400461183010d3ab98f3f326e4bb75e221b;p=vim 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) --- diff --git a/src/version.c b/src/version.c index 37da6ab15..5e177f09b 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2654, /**/ 2653, /**/ diff --git a/src/vim9execute.c b/src/vim9execute.c index 1ae17d97b..2eb0bec13 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -1067,13 +1067,22 @@ char_from_string(char_u *str, varnumber_T index) return NULL; 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) { int clen = 0; 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; if (nchar < 0) // 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) - 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) return NULL; return vim_strnsave(str + nbyte, mb_ptr2len(str + nbyte));