Skip to content

Commit 5f2d0c7

Browse files
committed
Optimized the performance of large literal tables (e.g., configuration tables).
1 parent 9ebaa0d commit 5f2d0c7

File tree

2 files changed

+64
-23
lines changed

2 files changed

+64
-23
lines changed

changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* `NEW` locale `es-419`, thanks [Felipe Lema](https://codeberg.org/FelipeLema)
77
* `FIX` prevent unnecessary edits by LSP formatting when content did not change
88
* `FIX` return no completions if completion is disabled
9+
* `FIX` optimized the performance of large literal tables (e.g., configuration tables)
910

1011
## 3.13.9
1112
`2025-3-13`

script/vm/compiler.lua

+63-23
Original file line numberDiff line numberDiff line change
@@ -174,36 +174,77 @@ local function searchFieldByGlobalID(suri, source, key, pushResult)
174174
end
175175
end
176176

177-
local searchFieldSwitch = util.switch()
178-
: case 'table'
179-
: call(function (_suri, source, key, pushResult)
180-
local hasFiled = false
177+
local VARARGKEY = {'<VARARGKEY>'}
178+
local function searchLiteralFieldFromTable(source, key, callback)
179+
local cache = source._literalFieldsCache
180+
local cache2 = source._literalFieldsCache2
181+
if not cache then
182+
cache = {}
183+
cache2 = {}
184+
source._literalFieldsCache = cache
185+
source._literalFieldsCache2 = cache2
186+
181187
for _, field in ipairs(source) do
188+
local fkey
182189
if field.type == 'tablefield'
183190
or field.type == 'tableindex' then
184-
local fieldKey = guide.getKeyName(field)
185-
if key == vm.ANY
186-
or key == fieldKey then
187-
hasFiled = true
188-
pushResult(field)
189-
end
191+
fkey = guide.getKeyName(field)
190192
end
191193
if field.type == 'tableexp' then
192-
if key == vm.ANY
193-
or key == field.tindex then
194-
hasFiled = true
195-
pushResult(field)
196-
end
194+
fkey = field.tindex
197195
end
198196
if field.type == 'varargs' then
199-
if not hasFiled
200-
and type(key) == 'number'
201-
and key >= 1
202-
and math.tointeger(key) then
203-
hasFiled = true
204-
pushResult(field)
197+
fkey = VARARGKEY
198+
end
199+
if fkey ~= nil then
200+
if cache[fkey] == nil then
201+
cache[fkey] = field
202+
else
203+
if cache2[fkey] == nil then
204+
cache2[fkey] = {}
205+
end
206+
cache2[fkey][#cache2[fkey]+1] = field
205207
end
206-
if key == vm.ANY then
208+
end
209+
end
210+
end
211+
local value = cache[key]
212+
if value ~= nil then
213+
callback(value)
214+
if cache2[key] then
215+
for _, field in ipairs(cache2[key]) do
216+
callback(field)
217+
end
218+
end
219+
return
220+
end
221+
if type(key) == 'number'
222+
and key >= 1
223+
and math.tointeger(key) then
224+
value = cache[VARARGKEY]
225+
end
226+
if value ~= nil then
227+
callback(value)
228+
if cache2[VARARGKEY] then
229+
for _, field in ipairs(cache2[VARARGKEY]) do
230+
callback(field)
231+
end
232+
end
233+
end
234+
end
235+
236+
local searchFieldSwitch = util.switch()
237+
: case 'table'
238+
: call(function (_suri, source, key, pushResult)
239+
if type(key) == 'string'
240+
or type(key) == 'number' then
241+
searchLiteralFieldFromTable(source, key, pushResult)
242+
elseif key == vm.ANY then
243+
for _, field in ipairs(source) do
244+
if field.type == 'tablefield'
245+
or field.type == 'tableindex'
246+
or field.type == 'tableexp'
247+
or field.type == 'varargs' then
207248
pushResult(field)
208249
end
209250
end
@@ -232,7 +273,6 @@ local searchFieldSwitch = util.switch()
232273
local fieldKey = guide.getKeyName(field)
233274
if key == vm.ANY
234275
or key == fieldKey then
235-
hasFiled = true
236276
pushResult(field)
237277
end
238278
::CONTINUE::

0 commit comments

Comments
 (0)