-
-
Save k0kubun/f66d6fe1e6ba821e4263257e504ba28f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ruby 3.2.0dev (2022-10-26T06:02:04Z master 94f3aa2126) [x86_64-linux] | |
Warming up -------------------------------------- | |
before 1.409M i/100ms | |
after 1.895M i/100ms | |
Calculating ------------------------------------- | |
before 13.931M (± 0.1%) i/s - 70.435M in 5.055915s | |
after 18.669M (± 0.3%) i/s - 94.769M in 5.076395s | |
Comparison: | |
after: 18668840.0 i/s | |
before: 13931312.1 i/s - 1.34x (± 0.00) slower |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'benchmark/ips' | |
require 'cgi' | |
require 'cgi/escape' | |
str = "string" | |
Benchmark.ips do |x| | |
x.report('before') { CGI.escapeHTML(str) } | |
x.report('after') { CGI.escapeHTML2(str) } | |
x.compare! | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/ext/cgi/escape/escape.c b/ext/cgi/escape/escape.c | |
index c5b76de596..508cd36f72 100644 | |
--- a/ext/cgi/escape/escape.c | |
+++ b/ext/cgi/escape/escape.c | |
@@ -75,6 +75,39 @@ optimized_escape_html(VALUE str) | |
return escaped; | |
} | |
+static VALUE | |
+optimized_escape_html2(VALUE str) | |
+{ | |
+ VALUE vbuf; | |
+ char *buf = ALLOCV_N(char, vbuf, escaped_length(str)); | |
+ const char *cstr = RSTRING_PTR(str); | |
+ const char *end = cstr + RSTRING_LEN(str); | |
+ | |
+ char *dest = buf; | |
+ while (cstr < end) { | |
+ const unsigned char c = *cstr++; | |
+ uint8_t len = html_escape_table[c].len; | |
+ if (len) { | |
+ memcpy(dest, html_escape_table[c].str, len); | |
+ dest += len; | |
+ } | |
+ else { | |
+ *dest++ = c; | |
+ } | |
+ } | |
+ | |
+ VALUE escaped; | |
+ if (RSTRING_LEN(str) < (dest - buf)) { | |
+ escaped = rb_str_new(buf, dest - buf); | |
+ preserve_original_state(str, escaped); | |
+ } | |
+ else { | |
+ escaped = str; | |
+ } | |
+ ALLOCV_END(vbuf); | |
+ return escaped; | |
+} | |
+ | |
static VALUE | |
optimized_unescape_html(VALUE str) | |
{ | |
@@ -324,6 +357,19 @@ cgiesc_escape_html(VALUE self, VALUE str) | |
} | |
} | |
+static VALUE | |
+cgiesc_escape_html2(VALUE self, VALUE str) | |
+{ | |
+ StringValue(str); | |
+ | |
+ if (rb_enc_str_asciicompat_p(str)) { | |
+ return optimized_escape_html2(str); | |
+ } | |
+ else { | |
+ return rb_call_super(1, &str); | |
+ } | |
+} | |
+ | |
/* | |
* call-seq: | |
* CGI.unescapeHTML(string) -> string | |
@@ -456,6 +502,7 @@ InitVM_escape(void) | |
rb_mEscape = rb_define_module_under(rb_cCGI, "Escape"); | |
rb_mUtil = rb_define_module_under(rb_cCGI, "Util"); | |
rb_define_method(rb_mEscape, "escapeHTML", cgiesc_escape_html, 1); | |
+ rb_define_method(rb_mEscape, "escapeHTML2", cgiesc_escape_html2, 1); | |
rb_define_method(rb_mEscape, "unescapeHTML", cgiesc_unescape_html, 1); | |
rb_define_method(rb_mEscape, "escapeURIComponent", cgiesc_escape_uri_component, 1); | |
rb_define_method(rb_mEscape, "unescapeURIComponent", cgiesc_unescape_uri_component, -1); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment