summaryrefslogtreecommitdiffhomepage
path: root/src/string.c
diff options
context:
space:
mode:
authorKOBAYASHI Shuji <[email protected]>2019-10-26 22:19:04 +0900
committerKOBAYASHI Shuji <[email protected]>2019-10-26 22:19:04 +0900
commitdb0a4d9045892e9f8b5760267dc80ff51cac4d22 (patch)
treeb754b7e5270821860fa546ffad1d55b41f191409 /src/string.c
parent9c994516077cbab2a850cc8e1ac9e93f1f2731fc (diff)
downloadmruby-db0a4d9045892e9f8b5760267dc80ff51cac4d22.tar.gz
mruby-db0a4d9045892e9f8b5760267dc80ff51cac4d22.zip
Optimize `chars2bytes` with `MRB_UTF8_STRING` to ASCII only string
### Benchmark (with `MRB_UTF8_STRING`) ``` $ mruby -e ' COUNT = 150000 SIZE = 10000 strs = Array.new(COUNT) do s = "a" * SIZE s.size # set `MRB_STR_ASCII` flag s end i = 0 t = Time.now while i < COUNT strs[i][-2..-1] = "" i += 1 end printf "%.2f sec\n", Time.now - t ' 1.10 sec # before 0.07 sec # after ```
Diffstat (limited to 'src/string.c')
-rw-r--r--src/string.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/src/string.c b/src/string.c
index 518b62ea3..e5c3a3843 100644
--- a/src/string.c
+++ b/src/string.c
@@ -330,16 +330,21 @@ utf8_strlen(mrb_value str)
static mrb_int
chars2bytes(mrb_value s, mrb_int off, mrb_int idx)
{
- mrb_int i, b, n;
- const char *p = RSTRING_PTR(s) + off;
- const char *e = RSTRING_END(s);
+ if (RSTR_ASCII_P(mrb_str_ptr(s))) {
+ return idx;
+ }
+ else {
+ mrb_int i, b, n;
+ const char *p = RSTRING_PTR(s) + off;
+ const char *e = RSTRING_END(s);
- for (b=i=0; p<e && i<idx; i++) {
- n = utf8len(p, e);
- b += n;
- p += n;
+ for (b=i=0; p<e && i<idx; i++) {
+ n = utf8len(p, e);
+ b += n;
+ p += n;
+ }
+ return b;
}
- return b;
}
/* map byte offset to character index */
@@ -603,7 +608,7 @@ str_range_to_bytes(mrb_value str, mrb_int *pos, mrb_int *len)
static inline mrb_value
str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
{
- if (!RSTR_ASCII_P(mrb_str_ptr(str))) str_range_to_bytes(str, &beg, &len);
+ str_range_to_bytes(str, &beg, &len);
return mrb_str_byte_subseq(mrb, str, beg, len);
}
#else