Skip to content

Commit 9ccc31e

Browse files
committed
⚡ Parse expected chars using String#getbyte
Using `string.getbyte(pos)` rather than `string[pos]` avoids the allocation of a temporary string object. This gives a speedup of ~5% to most benchmarks.
1 parent 53c370a commit 9ccc31e

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

lib/net/imap/response_parser/parser_utils.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module Generator
1515

1616
# we can skip lexer for single character matches, as a shortcut
1717
def def_char_matchers(name, char, token)
18+
byte = char.ord
1819
match_name = name.match(/\A[A-Z]/) ? "#{name}!" : name
1920
char = char.dump
2021
class_eval <<~RUBY, __FILE__, __LINE__ + 1
@@ -27,15 +28,15 @@ def lookahead_#{name}?
2728
2829
# use token or string peek
2930
def peek_#{name}?
30-
@token ? @token.symbol == #{token} : @str[@pos] == #{char}
31+
@token ? @token.symbol == #{token} : @str.getbyte(@pos) == #{byte}
3132
end
3233
3334
# like accept(token_symbols); returns token or nil
3435
def #{name}?
3536
if @token&.symbol == #{token}
3637
#{SHIFT_TOKEN}
3738
#{char}
38-
elsif !@token && @str[@pos] == #{char}
39+
elsif !@token && @str.getbyte(@pos) == #{byte}
3940
@pos += 1
4041
#{char}
4142
end
@@ -46,7 +47,7 @@ def #{match_name}
4647
if @token&.symbol == #{token}
4748
#{SHIFT_TOKEN}
4849
#{char}
49-
elsif !@token && @str[@pos] == #{char}
50+
elsif !@token && @str.getbyte(@pos) == #{byte}
5051
@pos += 1
5152
#{char}
5253
else
@@ -109,7 +110,6 @@ def #{match_name}
109110
end
110111
end
111112
RUBY
112-
113113
end
114114

115115
end

0 commit comments

Comments
 (0)