Skip to content

Commit 090d11a

Browse files
committed
⚡ Use frozen const when parsing empty arrays [🚧 WIP]
TODO, record benchmarks
1 parent 5a0e5cb commit 090d11a

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
@@ -62,6 +62,10 @@ def parse(str)
6262
T_TEXT = :TEXT # any char except CRLF
6363
T_EOF = :EOF # end of response string
6464

65+
# Use to avoid allocation when we know the result is empty
66+
EMPTY_ARRAY = [].freeze
67+
private_constant :EMPTY_ARRAY
68+
6569
module ResponseConditions
6670
OK = "OK"
6771
NO = "NO"
@@ -596,7 +600,7 @@ def tagged_ext_simple
596600
# "(" [tagged-ext-comp] ")"
597601
def tagged_ext_val
598602
if lpar?
599-
_ = peek_rpar? ? [] : tagged_ext_comp
603+
_ = peek_rpar? ? EMPTY_ARRAY : tagged_ext_comp
600604
rpar
601605
_
602606
else
@@ -1356,7 +1360,7 @@ def mailbox_data__list
13561360
# ; This is the list information pointed to by the ABNF
13571361
# ; item "mailbox-data", which is defined above
13581362
def mailbox_list
1359-
lpar; attr = peek_rpar? ? [] : mbx_list_flags; rpar
1363+
lpar; attr = peek_rpar? ? EMPTY_ARRAY : mbx_list_flags; rpar
13601364
SP!; delim = nquoted
13611365
SP!; name = mailbox
13621366
# TODO: mbox-list-extended
@@ -1456,8 +1460,12 @@ def acl_data
14561460
# obsolete-search-response = "SEARCH" *(SP nz-number)
14571461
def mailbox_data__search
14581462
name = label_in("SEARCH", "SORT")
1459-
data = []
1460-
while _ = SP? && nz_number? do data << _ end
1463+
if (_ = SP? && nz_number?)
1464+
data = [_]
1465+
while _ = SP? && nz_number? do data << _ end
1466+
else
1467+
data = EMPTY_ARRAY
1468+
end
14611469
if lpar?
14621470
label("MODSEQ"); SP!
14631471
modseq = mod_sequence_value
@@ -1506,7 +1514,7 @@ def thread_members
15061514
else nested = thread_nested; break
15071515
end
15081516
end
1509-
members.reverse.inject(nested || []) {|subthreads, number|
1517+
members.reverse.inject(nested || EMPTY_ARRAY) {|subthreads, number|
15101518
[ThreadMember.new(number, subthreads)]
15111519
}.first
15121520
end
@@ -1678,7 +1686,7 @@ def namespace_response
16781686

16791687
# namespace = nil / "(" 1*namespace-descr ")"
16801688
def namespace
1681-
NIL? and return []
1689+
NIL? and return EMPTY_ARRAY
16821690
lpar
16831691
list = [namespace_descr]
16841692
list << namespace_descr until rpar?
@@ -1805,13 +1813,13 @@ def resp_text_code
18051813
data =
18061814
case name
18071815
when "CAPABILITY" then resp_code__capability
1808-
when "PERMANENTFLAGS" then SP? ? flag_perm__list : []
1816+
when "PERMANENTFLAGS" then SP? ? flag_perm__list : EMPTY_ARRAY
18091817
when "UIDNEXT" then SP!; nz_number
18101818
when "UIDVALIDITY" then SP!; nz_number
18111819
when "UNSEEN" then SP!; nz_number # rev1 only
18121820
when "APPENDUID" then SP!; resp_code_apnd__data # rev2, UIDPLUS
18131821
when "COPYUID" then SP!; resp_code_copy__data # rev2, UIDPLUS
1814-
when "BADCHARSET" then SP? ? charset__list : []
1822+
when "BADCHARSET" then SP? ? charset__list : EMPTY_ARRAY
18151823
when "ALERT", "PARSE", "READ-ONLY", "READ-WRITE", "TRYCREATE",
18161824
"UNAVAILABLE", "AUTHENTICATIONFAILED", "AUTHORIZATIONFAILED",
18171825
"EXPIRED", "PRIVACYREQUIRED", "CONTACTADMIN", "NOPERM", "INUSE",
@@ -1942,7 +1950,7 @@ def x_gm_label; accept(T_BSLASH) ? atom.capitalize.to_sym : astring end
19421950

19431951
# See https://developers.google.com/gmail/imap/imap-extensions
19441952
def x_gm_labels
1945-
lpar; return [] if rpar?
1953+
lpar; return EMPTY_ARRAY if rpar?
19461954
labels = []
19471955
labels << x_gm_label
19481956
labels << x_gm_label while SP?

0 commit comments

Comments
 (0)