[前][次][番号順一覧][スレッド一覧]

ruby-changes:74363

From: Takashi <ko1@a...>
Date: Sat, 5 Nov 2022 15:59:02 +0900 (JST)
Subject: [ruby-changes:74363] 419d2fc14d (master): [ruby/erb] Optimize the no-escape case with strpbrk

https://git.ruby-lang.org/ruby.git/commit/?id=419d2fc14d

From 419d2fc14d2bedc6d5a7080ee80df8330884ea6c Mon Sep 17 00:00:00 2001
From: Takashi Kokubun <takashikkbn@g...>
Date: Fri, 4 Nov 2022 23:58:43 -0700
Subject: [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.
---
 ext/erb/erb.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/ext/erb/erb.c b/ext/erb/erb.c
index c90f77f7b1..1e4842c793 100644
--- a/ext/erb/erb.c
+++ b/ext/erb/erb.c
@@ -38,6 +38,12 @@ escaped_length(VALUE str) https://github.com/ruby/ruby/blob/trunk/ext/erb/erb.c#L38
 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) https://github.com/ruby/ruby/blob/trunk/ext/erb/erb.c#L62
         }
     }
 
-    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;
 }
-- 
cgit v1.2.3


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]