mirror of
https://github.com/ruby/ruby.git
synced 2026-10-28 16:36:20 +08:00
The fast path is now 4.4x faster, now making it ~2.6x times
faster than `CGI.escape_html`, and 26x faster than an equivalent
`gsub`.
```
compare-ruby: ruby 4.1.0dev (2026-09-06T11:22:48Z master 13fc4ffd32) +YJIT +PRISM [arm64-darwin25]
built-ruby: ruby 4.1.0dev (2026-09-06T14:39:43Z string-tr-simd e2526ca9ba) +YJIT +PRISM [arm64-darwin25]
``
| |compare-ruby|built-ruby|
|:------------|-----------:|---------:|
|tr_escape | 41.595k| 182.732k|
| | -| 4.39x|
|gsub_escape | 7.135k| 6.977k|
| | 1.02x| -|
|cgi_escape | 70.117k| 70.179k|
| | -| 1.00x|
However, contrary to a lookup table, here the performance is linear with
the number of characters to match, hence once we're looking for 16 distinct
bytes, the gain compared to the lookup table is down to ~2x.
24 lines
450 B
YAML
24 lines
450 B
YAML
prelude: |
|
|
# frozen_string_literal: true
|
|
|
|
require 'cgi/escape'
|
|
|
|
STR = ((("a" * 31) + "<") * 1000).freeze
|
|
|
|
ESCAPED_CHARS = {
|
|
"\\" => "'",
|
|
"\"" => """,
|
|
">" => '>',
|
|
"<" => '<',
|
|
"&" => '&',
|
|
}.freeze
|
|
ESCAPE_PATTERN = Regexp.union(ESCAPED_CHARS.keys)
|
|
|
|
benchmark:
|
|
tr_escape: |
|
|
STR.tr(ESCAPED_CHARS)
|
|
gsub_escape: |
|
|
STR.gsub(ESCAPE_PATTERN, ESCAPED_CHARS)
|
|
cgi_escape: |
|
|
CGI.escape_html(STR)
|