Skip to content

Commit 0d5aace

Browse files
committed
⚡ Use frozen const when parsing empty arrays [🚧 WIP]
TODO, record benchmarks
1 parent 62710b9 commit 0d5aace

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

lib/net/imap/response_parser.rb

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ def parse(str)
6666
T_TEXT = :TEXT # any char except CRLF
6767
T_EOF = :EOF # end of response string
6868

69+
# Use to avoid allocation when we know the result is empty
70+
EMPTY_ARRAY = [].freeze
71+
private_constant :EMPTY_ARRAY
72+
6973
module ResponseConditions
7074
OK = "OK"
7175
NO = "NO"
@@ -618,7 +622,7 @@ def tagged_ext_simple
618622
# "(" [tagged-ext-comp] ")"
619623
def tagged_ext_val
620624
if lpar?
621-
_ = peek_rpar? ? [] : tagged_ext_comp
625+
_ = peek_rpar? ? EMPTY_ARRAY : tagged_ext_comp
622626
rpar
623627
_
624628
else
@@ -1397,7 +1401,7 @@ def mailbox_data__list
13971401
# ; This is the list information pointed to by the ABNF
13981402
# ; item "mailbox-data", which is defined above
13991403
def mailbox_list
1400-
lpar; attr = peek_rpar? ? [] : mbx_list_flags; rpar
1404+
lpar; attr = peek_rpar? ? EMPTY_ARRAY : mbx_list_flags; rpar
14011405
SP!; delim = nquoted
14021406
SP!; name = mailbox
14031407
# TODO: mbox-list-extended
@@ -1497,8 +1501,12 @@ def acl_data
14971501
# obsolete-search-response = "SEARCH" *(SP nz-number)
14981502
def mailbox_data__search
14991503
name = label_in("SEARCH", "SORT")
1500-
data = []
1501-
while _ = SP? && nz_number? do data << _ end
1504+
if (_ = SP? && nz_number?)
1505+
data = [_]
1506+
while _ = SP? && nz_number? do data << _ end
1507+
else
1508+
data = EMPTY_ARRAY
1509+
end
15021510
if lpar?
15031511
label("MODSEQ"); SP!
15041512
modseq = mod_sequence_value
@@ -1652,7 +1660,7 @@ def thread_members
16521660
else nested = thread_nested; break
16531661
end
16541662
end
1655-
members.reverse.inject(nested || []) {|subthreads, number|
1663+
members.reverse.inject(nested || EMPTY_ARRAY) {|subthreads, number|
16561664
[ThreadMember.new(number, subthreads)]
16571665
}.first
16581666
end
@@ -1824,7 +1832,7 @@ def namespace_response
18241832

18251833
# namespace = nil / "(" 1*namespace-descr ")"
18261834
def namespace
1827-
NIL? and return []
1835+
NIL? and return EMPTY_ARRAY
18281836
lpar
18291837
list = [namespace_descr]
18301838
list << namespace_descr until rpar?
@@ -1954,13 +1962,13 @@ def resp_text_code
19541962
data =
19551963
case name
19561964
when "CAPABILITY" then resp_code__capability
1957-
when "PERMANENTFLAGS" then SP? ? flag_perm__list : []
1965+
when "PERMANENTFLAGS" then SP? ? flag_perm__list : EMPTY_ARRAY
19581966
when "UIDNEXT" then SP!; nz_number
19591967
when "UIDVALIDITY" then SP!; nz_number
19601968
when "UNSEEN" then SP!; nz_number # rev1 only
19611969
when "APPENDUID" then SP!; resp_code_apnd__data # rev2, UIDPLUS
19621970
when "COPYUID" then SP!; resp_code_copy__data # rev2, UIDPLUS
1963-
when "BADCHARSET" then SP? ? charset__list : []
1971+
when "BADCHARSET" then SP? ? charset__list : EMPTY_ARRAY
19641972
when "ALERT", "PARSE", "READ-ONLY", "READ-WRITE", "TRYCREATE",
19651973
"UNAVAILABLE", "AUTHENTICATIONFAILED", "AUTHORIZATIONFAILED",
19661974
"EXPIRED", "PRIVACYREQUIRED", "CONTACTADMIN", "NOPERM", "INUSE",
@@ -2109,7 +2117,7 @@ def x_gm_label; accept(T_BSLASH) ? atom.capitalize.to_sym : astring end
21092117

21102118
# See https://developers.google.com/gmail/imap/imap-extensions
21112119
def x_gm_labels
2112-
lpar; return [] if rpar?
2120+
lpar; return EMPTY_ARRAY if rpar?
21132121
labels = []
21142122
labels << x_gm_label
21152123
labels << x_gm_label while SP?

0 commit comments

Comments
 (0)