diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-03-26 13:34:05 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-03-26 13:34:05 +0100 |
commit | ff871400461183010d3ab98f3f326e4bb75e221b (patch) | |
tree | 553f27a2cc111081ed9cde957396441e95dbde02 | |
parent | 3a0f092ac0dbdd4ce71f9c4abe020e89f13df36c (diff) |
patch 8.2.2654: Vim9: getting a character from a string can be slowv8.2.2654
Problem: Vim9: getting a character from a string can be slow.
Solution: Avoid a function call to get the character byte size. (#8000)
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9execute.c | 22 |
2 files changed, 21 insertions, 3 deletions
diff --git a/src/version.c b/src/version.c index 37da6ab15f..5e177f09b3 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2654, +/**/ 2653, /**/ 2652, diff --git a/src/vim9execute.c b/src/vim9execute.c index 1ae17d97bf..2eb0bec13d 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)); |