Skip to content

Commit

Permalink
⚡ Use frozen const when parsing empty arrays [🚧 WIP]
Browse files Browse the repository at this point in the history
TODO, record benchmarks
  • Loading branch information
nevans committed Jun 22, 2024
1 parent e588adb commit 9771e1a
Showing 1 changed file with 17 additions and 9 deletions.
26 changes: 17 additions & 9 deletions lib/net/imap/response_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ def parse(str)
T_TEXT = :TEXT # any char except CRLF
T_EOF = :EOF # end of response string

# Use to avoid allocation when we know the result is empty
EMPTY_ARRAY = [].freeze
private_constant :EMPTY_ARRAY

module ResponseConditions
OK = "OK"
NO = "NO"
Expand Down Expand Up @@ -596,7 +600,7 @@ def tagged_ext_simple
# "(" [tagged-ext-comp] ")"
def tagged_ext_val
if lpar?
_ = peek_rpar? ? [] : tagged_ext_comp
_ = peek_rpar? ? EMPTY_ARRAY : tagged_ext_comp
rpar
_
else
Expand Down Expand Up @@ -1367,7 +1371,7 @@ def mailbox_data__list
# ; This is the list information pointed to by the ABNF
# ; item "mailbox-data", which is defined above
def mailbox_list
lpar; attr = peek_rpar? ? [] : mbx_list_flags; rpar
lpar; attr = peek_rpar? ? EMPTY_ARRAY : mbx_list_flags; rpar
SP!; delim = nquoted
SP!; name = mailbox
# TODO: mbox-list-extended
Expand Down Expand Up @@ -1467,8 +1471,12 @@ def acl_data
# obsolete-search-response = "SEARCH" *(SP nz-number)
def mailbox_data__search
name = label_in("SEARCH", "SORT")
data = []
while _ = SP? && nz_number? do data << _ end
if (_ = SP? && nz_number?)
data = [_]
while _ = SP? && nz_number? do data << _ end
else
data = EMPTY_ARRAY
end
if lpar?
label("MODSEQ"); SP!
modseq = mod_sequence_value
Expand Down Expand Up @@ -1517,7 +1525,7 @@ def thread_members
else nested = thread_nested; break
end
end
members.reverse.inject(nested || []) {|subthreads, number|
members.reverse.inject(nested || EMPTY_ARRAY) {|subthreads, number|
[ThreadMember.new(number, subthreads)]
}.first
end
Expand Down Expand Up @@ -1689,7 +1697,7 @@ def namespace_response

# namespace = nil / "(" 1*namespace-descr ")"
def namespace
NIL? and return []
NIL? and return EMPTY_ARRAY
lpar
list = [namespace_descr]
list << namespace_descr until rpar?
Expand Down Expand Up @@ -1816,13 +1824,13 @@ def resp_text_code
data =
case name
when "CAPABILITY" then resp_code__capability
when "PERMANENTFLAGS" then SP? ? flag_perm__list : []
when "PERMANENTFLAGS" then SP? ? flag_perm__list : EMPTY_ARRAY
when "UIDNEXT" then SP!; nz_number
when "UIDVALIDITY" then SP!; nz_number
when "UNSEEN" then SP!; nz_number # rev1 only
when "APPENDUID" then SP!; resp_code_apnd__data # rev2, UIDPLUS
when "COPYUID" then SP!; resp_code_copy__data # rev2, UIDPLUS
when "BADCHARSET" then SP? ? charset__list : []
when "BADCHARSET" then SP? ? charset__list : EMPTY_ARRAY
when "ALERT", "PARSE", "READ-ONLY", "READ-WRITE", "TRYCREATE",
"UNAVAILABLE", "AUTHENTICATIONFAILED", "AUTHORIZATIONFAILED",
"EXPIRED", "PRIVACYREQUIRED", "CONTACTADMIN", "NOPERM", "INUSE",
Expand Down Expand Up @@ -1953,7 +1961,7 @@ def x_gm_label; accept(T_BSLASH) ? atom.capitalize.to_sym : astring end

# See https://developers.google.com/gmail/imap/imap-extensions
def x_gm_labels
lpar; return [] if rpar?
lpar; return EMPTY_ARRAY if rpar?
labels = []
labels << x_gm_label
labels << x_gm_label while SP?
Expand Down

0 comments on commit 9771e1a

Please sign in to comment.