[ruby/erb] Optimize the no-escape case with strpbrk

(https://github.com/ruby/erb/pull/29)

Typically, strpbrk(3) is optimized pretty well with SIMD instructions.
Just using it makes this as fast as a SIMD-based implementation for the
no-escape case.

Not utilizing this for escaped cases because memory allocation would be
a more significant bottleneck for many strings anyway. Also, there'll be
some overhead in calling a C function (strpbrk) many times because we're
not using SIMD instructions directly. So using strpbrk all the time
might not necessarily be faster.
This commit is contained in:
Takashi Kokubun 2022-11-04 23:58:43 -07:00 committed by git
parent f276d5a7fe
commit 419d2fc14d

View File

@ -38,6 +38,12 @@ escaped_length(VALUE str)
static VALUE
optimized_escape_html(VALUE str)
{
// Optimize the most common, no-escape case with strpbrk(3). Not using it after
// this because calling a C function many times could be slower for some cases.
if (strpbrk(RSTRING_PTR(str), "'&\"<>") == NULL) {
return str;
}
VALUE vbuf;
char *buf = ALLOCV_N(char, vbuf, escaped_length(str));
const char *cstr = RSTRING_PTR(str);
@ -56,11 +62,8 @@ optimized_escape_html(VALUE str)
}
}
VALUE escaped = str;
if (RSTRING_LEN(str) < (dest - buf)) {
escaped = rb_str_new(buf, dest - buf);
preserve_original_state(str, escaped);
}
VALUE escaped = rb_str_new(buf, dest - buf);
preserve_original_state(str, escaped);
ALLOCV_END(vbuf);
return escaped;
}