From fb8bc1954b805e57492266b0fa2f6c255901a52d Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 11 Jan 2024 18:22:26 +0900 Subject: [PATCH] string.c: improve performance of chars2bytes/bytes2chars; ref #6143 --- src/string.c | 53 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/src/string.c b/src/string.c index 63aa48371..a26bad4a3 100644 --- a/src/string.c +++ b/src/string.c @@ -264,6 +264,18 @@ mrb_gc_free_str(mrb_state *mrb, struct RString *str) } #ifdef MRB_UTF8_STRING + +#define NOASCII(c) ((c) & 0x80) + +static const char* +search_nonascii(const char* p, const char *e) +{ + for (; p < e; ++p) { + if (NOASCII(*p)) return p; + } + return e; +} + #define utf8_islead(c) ((unsigned char)((c)&0xc0) != 0x80) extern const char mrb_utf8len_table[]; @@ -279,7 +291,6 @@ mrb_utf8len(const char* p, const char* e) if (len > e - p) return 1; switch (len) { case 0: - case 1: return 1; case 4: if (utf8_islead(p[3])) return 1; @@ -333,14 +344,29 @@ chars2bytes(mrb_value s, mrb_int off, mrb_int idx) const char *p0 = RSTRING_PTR(s) + off; const char *p = p0; const char *e = RSTRING_END(s); + mrb_int i = 0; - while (p < e && idx--) { - if ((*p & 0x80) == 0) p++; - else p += mrb_utf8len(p, e); + while (p 0) len++; + if (i