Skip to content

Commit 875f4c6

Browse files
committed
Optimize Source#read_until method
## Benchmark ``` RUBYLIB= BUNDLER_ORIG_RUBYLIB= /Users/naitoh/.rbenv/versions/3.3.0/bin/ruby -v -S benchmark-driver /Users/naitoh/ghq/github.com/naitoh/rexml/benchmark/parse.yaml ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin22] Calculating ------------------------------------- before after before(YJIT) after(YJIT) dom 9.877 9.992 15.605 17.559 i/s - 100.000 times in 10.124592s 10.008017s 6.408031s 5.695167s sax 22.903 25.151 39.482 50.846 i/s - 100.000 times in 4.366300s 3.975922s 2.532822s 1.966706s pull 25.940 30.474 44.685 61.450 i/s - 100.000 times in 3.855070s 3.281511s 2.237879s 1.627346s stream 25.255 29.500 41.819 53.605 i/s - 100.000 times in 3.959539s 3.389825s 2.391256s 1.865505s Comparison: dom after(YJIT): 17.6 i/s before(YJIT): 15.6 i/s - 1.13x slower after: 10.0 i/s - 1.76x slower before: 9.9 i/s - 1.78x slower sax after(YJIT): 50.8 i/s before(YJIT): 39.5 i/s - 1.29x slower after: 25.2 i/s - 2.02x slower before: 22.9 i/s - 2.22x slower pull after(YJIT): 61.4 i/s before(YJIT): 44.7 i/s - 1.38x slower after: 30.5 i/s - 2.02x slower before: 25.9 i/s - 2.37x slower stream after(YJIT): 53.6 i/s before(YJIT): 41.8 i/s - 1.28x slower after: 29.5 i/s - 1.82x slower before: 25.3 i/s - 2.12x slower ``` - YJIT=ON : 1.13x - 1.38x faster - YJIT=OFF : 1.01x - 1.17x faster
1 parent 3e3893d commit 875f4c6

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

lib/rexml/source.rb

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ class Source
3434
attr_reader :line
3535
attr_reader :encoding
3636

37+
module Private
38+
PRE_DEFINED_TERM_PATTERNS = {}
39+
pre_defined_terms = ["'", '"']
40+
pre_defined_terms.each do |term|
41+
PRE_DEFINED_TERM_PATTERNS[term] = /#{Regexp.escape(term)}/
42+
end
43+
end
44+
private_constant :Private
45+
include Private
46+
3747
# Constructor
3848
# @param arg must be a String, and should be a valid XML document
3949
# @param encoding if non-null, sets the encoding of the source to this
@@ -69,7 +79,8 @@ def read(term = nil)
6979
end
7080

7181
def read_until(term)
72-
data = @scanner.scan_until(/#{Regexp.escape(term)}/)
82+
pattern = Private::PRE_DEFINED_TERM_PATTERNS[term] || /#{Regexp.escape(term)}/
83+
data = @scanner.scan_until(pattern)
7384
unless data
7485
data = @scanner.rest
7586
@scanner.pos = @scanner.string.bytesize
@@ -179,7 +190,7 @@ def read(term = nil)
179190
end
180191

181192
def read_until(term)
182-
pattern = /#{Regexp.escape(term)}/
193+
pattern = Private::PRE_DEFINED_TERM_PATTERNS[term] || /#{Regexp.escape(term)}/
183194
term = encode(term)
184195
begin
185196
until str = @scanner.scan_until(pattern)

0 commit comments

Comments
 (0)