Skip to content

Commit 18721bd

Browse files
CopilotCapsAdmin
andcommitted
Optimize hot paths: reduce allocations and improve loop efficiency
Co-authored-by: CapsAdmin <204157+CapsAdmin@users.noreply.github.com>
1 parent ef31e2e commit 18721bd

4 files changed

Lines changed: 56 additions & 50 deletions

File tree

nattlua/parser/node.lua

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,31 +1034,37 @@ local NAN_TYPE = {}
10341034
local ANY_TYPE = {}
10351035

10361036
function META:AssociateType(obj)
1037-
self.inferred_types_done = self.inferred_types_done or {}
1038-
self.inferred_types = self.inferred_types or {}
1039-
1040-
do
1041-
local t = obj.Type
1042-
local hash = obj
1043-
1044-
if hash.Type == "symbol" then
1045-
hash = obj.Data
1046-
elseif obj.Type == "string" then
1047-
hash = obj.Data or STRING_TYPE
1048-
elseif obj.Type == "number" then
1049-
hash = obj.Data or NUMBER_TYPE
1050-
1051-
if hash ~= hash then hash = NAN_TYPE end
1052-
elseif obj.Type == "any" then
1053-
hash = ANY_TYPE
1054-
end
1037+
local done = self.inferred_types_done
1038+
local types = self.inferred_types
1039+
1040+
if not done then
1041+
done = {}
1042+
self.inferred_types_done = done
1043+
end
1044+
1045+
if not types then
1046+
types = {}
1047+
self.inferred_types = types
1048+
end
10551049

1056-
if self.inferred_types_done[hash] then return end
1050+
local obj_type = obj.Type
1051+
local hash = obj
10571052

1058-
self.inferred_types_done[hash] = true
1053+
if obj_type == "symbol" then
1054+
hash = obj.Data
1055+
elseif obj_type == "string" then
1056+
hash = obj.Data or STRING_TYPE
1057+
elseif obj_type == "number" then
1058+
hash = obj.Data or NUMBER_TYPE
1059+
if hash ~= hash then hash = NAN_TYPE end
1060+
elseif obj_type == "any" then
1061+
hash = ANY_TYPE
10591062
end
10601063

1061-
self.inferred_types[#self.inferred_types + 1] = obj
1064+
if done[hash] then return end
1065+
1066+
done[hash] = true
1067+
types[#types + 1] = obj
10621068
end
10631069

10641070
function META:GetAssociatedTypes()

nattlua/types/number.lua

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -92,21 +92,7 @@ end
9292
function META.Equal(a--[[#: TNumber]], b--[[#: TBaseType]])
9393
if a.Type ~= b.Type then return false, "types differ" end
9494

95-
do
96-
return a.Hash == b.Hash
97-
end
98-
99-
if a.Data == b.Data then return true, "max values are equal" end
100-
101-
if not a.Data and not b.Data then
102-
return true, "no literal data in either value"
103-
else
104-
if a:IsNan() and b:IsNan() then return true, "both values are nan" end
105-
106-
return a.Data == b.Data, "literal values are equal"
107-
end
108-
109-
return false, "values are not equal"
95+
return a.Hash == b.Hash, "hash values are equal"
11096
end
11197

11298
function META:IsLiteral()

nattlua/types/table.lua

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,8 +675,11 @@ function META:FindKeyValWide(key--[[#: TBaseType]], reverse--[[#: boolean | nil]
675675
if keyval then return keyval end
676676

677677
local reasons = {}
678+
local data = self.Data
679+
local len = #data
678680

679-
for i, keyval in ipairs(self.Data) do
681+
for i = 1, len do
682+
local keyval = data[i]
680683
if key:Equal(keyval.key) then return keyval end
681684

682685
local ok, reason

nattlua/types/union.lua

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,9 @@ function META.Equal(
8181
end
8282

8383
function META:GetHash(visited)--[[#: string]]
84-
if self:GetCardinality() == 1 then
85-
return (self.Data[1]--[[# as any]]):GetHash()
84+
local data = self.Data
85+
if #data == 1 then
86+
return (data[1]--[[# as any]]):GetHash()
8687
end
8788

8889
visited = visited or {}
@@ -91,14 +92,16 @@ function META:GetHash(visited)--[[#: string]]
9192

9293
visited[self] = "*circular*"
9394
local types = {}
95+
local len = #data
9496

95-
for i, v in ipairs(self.Data) do
96-
types[i] = v:GetHash(visited)
97+
for i = 1, len do
98+
types[i] = data[i]:GetHash(visited)
9799
end
98100

99101
table_sort(types)
100-
visited[self] = table.concat(types, "|")
101-
return visited[self]--[[# as string]]
102+
local hash = table_concat(types, "|")
103+
visited[self] = hash
104+
return hash
102105
end
103106

104107
local sort = function(a--[[#: string]], b--[[#: string]])
@@ -110,9 +113,12 @@ function META:__tostring()
110113

111114
local s = {}
112115
self.suppress = true
116+
117+
local data = self.Data
118+
local len = #data
113119

114-
for i, v in ipairs(self.Data) do
115-
s[i] = tostring(v)
120+
for i = 1, len do
121+
s[i] = tostring(data[i])
116122
end
117123

118124
if not s[1] then
@@ -122,7 +128,7 @@ function META:__tostring()
122128

123129
self.suppress = false
124130

125-
if #s == 1 then return (s[1]--[[# as string]]) .. "|" end
131+
if len == 1 then return (s[1]--[[# as string]]) .. "|" end
126132

127133
table_sort(s, sort)
128134
return table_concat(s, " | ")
@@ -155,11 +161,16 @@ local function remove(self--[[#: TUnion]], index--[[#: number]])
155161
end
156162

157163
local function find_index(self--[[#: TUnion]], obj--[[#: any]])
158-
for i = 1, #self.Data do
159-
local v = self.Data[i]--[[# as any]]
164+
local data = self.Data
165+
local len = #data
166+
local obj_type = obj.Type
160167

161-
if v:Equal(obj) then
162-
if v.Type ~= "function" or v:GetFunctionBodyNode() == obj:GetFunctionBodyNode() then
168+
for i = 1, len do
169+
local v = data[i]--[[# as any]]
170+
171+
-- Early exit if types don't match
172+
if v.Type == obj_type and v:Equal(obj) then
173+
if obj_type ~= "function" or v:GetFunctionBodyNode() == obj:GetFunctionBodyNode() then
163174
return i
164175
end
165176
end

0 commit comments

Comments
 (0)