diff options
author | Paul Emmerich <tandanu@deadlybossmods.com> | 2024-05-24 16:04:27 +0200 |
---|---|---|
committer | Paul Emmerich <tandanu@deadlybossmods.com> | 2024-05-24 22:22:16 +0200 |
commit | 439c1e79611c240ea977936edc8f1fcadcbf34da (patch) | |
tree | 58b93b6f03f1af6d251b6b14abb888b058e990d2 | |
parent | 87abc4245f2a24e1cc35851b6464af9588934286 (diff) | |
download | lua-language-server-439c1e79611c240ea977936edc8f1fcadcbf34da.zip |
Throttle calls to await.delay() in some diagnostics
These 5 diagnostics cause ~70% of all calls to await.delay() by
diagnostics which in turn is about ~20% of the total runtime of
diagnostics.
Out of these diagnostics only assign-type-mismatch commonly exceeds
runtimes of 100ms (worst observed in my dataset was 7 seconds) and
even then it still attempts to call await.delay() over 1500 times
per second, so throttling by a factor of 15 is still fine.
-rw-r--r-- | script/await.lua | 22 | ||||
-rw-r--r-- | script/core/diagnostics/assign-type-mismatch.lua | 3 | ||||
-rw-r--r-- | script/core/diagnostics/need-check-nil.lua | 3 | ||||
-rw-r--r-- | script/core/diagnostics/redundant-value.lua | 3 | ||||
-rw-r--r-- | script/core/diagnostics/trailing-space.lua | 3 | ||||
-rw-r--r-- | script/core/diagnostics/unbalanced-assignments.lua | 3 |
6 files changed, 32 insertions, 5 deletions
diff --git a/script/await.lua b/script/await.lua index 22745570..f252197f 100644 --- a/script/await.lua +++ b/script/await.lua @@ -176,6 +176,28 @@ function m.delay() return coroutine.yield() end +local throttledDelayer = {} +throttledDelayer.__index = throttledDelayer + +---@async +function throttledDelayer:delay() + if not m._enable then + return + end + self.calls = self.calls + 1 + if self.calls == self.factor then + self.calls = 0 + return m.delay() + end +end + +function m.newThrottledDelayer(factor) + return setmetatable({ + factor = factor, + calls = 0, + }, throttledDelayer) +end + --- stop then close ---@async function m.stop() diff --git a/script/core/diagnostics/assign-type-mismatch.lua b/script/core/diagnostics/assign-type-mismatch.lua index 8472e87c..6fa26553 100644 --- a/script/core/diagnostics/assign-type-mismatch.lua +++ b/script/core/diagnostics/assign-type-mismatch.lua @@ -52,13 +52,14 @@ return function (uri, callback) return end + local delayer = await.newThrottledDelayer(15) ---@async guide.eachSourceTypes(state.ast, checkTypes, function (source) local value = source.value if not value then return end - await.delay() + delayer:delay() if source.type == 'setlocal' then local locNode = vm.compileNode(source.node) if not locNode.hasDefined then diff --git a/script/core/diagnostics/need-check-nil.lua b/script/core/diagnostics/need-check-nil.lua index 9c86939a..fe72d4ba 100644 --- a/script/core/diagnostics/need-check-nil.lua +++ b/script/core/diagnostics/need-check-nil.lua @@ -11,9 +11,10 @@ return function (uri, callback) return end + local delayer = await.newThrottledDelayer(500) ---@async guide.eachSourceType(state.ast, 'getlocal', function (src) - await.delay() + delayer:delay() local checkNil local nxt = src.next if nxt then diff --git a/script/core/diagnostics/redundant-value.lua b/script/core/diagnostics/redundant-value.lua index 6f60303b..ceb090c9 100644 --- a/script/core/diagnostics/redundant-value.lua +++ b/script/core/diagnostics/redundant-value.lua @@ -11,8 +11,9 @@ return function (uri, callback) return end + local delayer = await.newThrottledDelayer(50000) guide.eachSource(state.ast, function (src) ---@async - await.delay() + delayer:delay() if src.redundant then callback { start = src.start, diff --git a/script/core/diagnostics/trailing-space.lua b/script/core/diagnostics/trailing-space.lua index 2e0398b2..1fdccf80 100644 --- a/script/core/diagnostics/trailing-space.lua +++ b/script/core/diagnostics/trailing-space.lua @@ -10,9 +10,10 @@ return function (uri, callback) if not state or not text then return end + local delayer = await.newThrottledDelayer(5000) local lines = state.lines for i = 0, #lines do - await.delay() + delayer:delay() local startOffset = lines[i] local finishOffset = text:find('[\r\n]', startOffset) or (#text + 1) local lastOffset = finishOffset - 1 diff --git a/script/core/diagnostics/unbalanced-assignments.lua b/script/core/diagnostics/unbalanced-assignments.lua index c21ca993..f72e1fd5 100644 --- a/script/core/diagnostics/unbalanced-assignments.lua +++ b/script/core/diagnostics/unbalanced-assignments.lua @@ -41,9 +41,10 @@ return function (uri, callback, code) end end + local delayer = await.newThrottledDelayer(1000) ---@async guide.eachSourceTypes(ast.ast, types, function (source) - await.delay() + delayer:delay() checkSet(source) end) end |