diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2021-01-05 21:23:38 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2021-01-05 21:23:38 +0800 |
commit | b62eba6d93fc026873d29dc865cd3f745cb403fd (patch) | |
tree | 9ddb1bb78113f8201e634a2e3c305f4e0985d02f | |
parent | a6cfc1162c24e1621076bc96b36768873bbaf9d4 (diff) | |
download | lua-language-server-b62eba6d93fc026873d29dc865cd3f745cb403fd.zip |
improve performance
-rw-r--r-- | script/core/completion.lua | 23 | ||||
-rw-r--r-- | script/files.lua | 6 | ||||
-rw-r--r-- | script/parser/guide.lua | 8 | ||||
-rw-r--r-- | script/parser/luadoc.lua | 77 | ||||
-rw-r--r-- | script/plugin.lua | 2 | ||||
-rw-r--r-- | script/provider/provider.lua | 1 | ||||
-rw-r--r-- | script/vm/getGlobals.lua | 2 | ||||
-rw-r--r-- | test/full/example.lua | 15 |
8 files changed, 103 insertions, 31 deletions
diff --git a/script/core/completion.lua b/script/core/completion.lua index 16ebaca0..0762a194 100644 --- a/script/core/completion.lua +++ b/script/core/completion.lua @@ -604,6 +604,9 @@ local function checkCommon(ast, word, text, offset, results) if config.config.completion.workspaceWord and #word >= 2 then local myHead = word:sub(1, 2) for uri in files.eachFile() do + if #results >= 100 then + break + end if myUri and files.eq(myUri, uri) then goto CONTINUE end @@ -623,6 +626,9 @@ local function checkCommon(ast, word, text, offset, results) end end for _, str in ipairs(cache.commonWords[myHead] or {}) do + if #results >= 100 then + break + end if not used[str] and str ~= word then used[str] = true @@ -637,8 +643,14 @@ local function checkCommon(ast, word, text, offset, results) ::CONTINUE:: end for uri in files.eachDll() do + if #results >= 100 then + break + end local words = files.getDllWords(uri) or {} for _, str in ipairs(words) do + if #results >= 100 then + break + end if #str >= 3 and not used[str] and str ~= word then used[str] = true if matchKey(word, str) then @@ -652,6 +664,9 @@ local function checkCommon(ast, word, text, offset, results) end end for str, pos in text:gmatch '([%a_][%w_]+)()' do + if #results >= 100 then + break + end if #str >= 3 and not used[str] and pos - 1 ~= offset then used[str] = true if matchKey(word, str) then @@ -1216,7 +1231,9 @@ local function trySymbol(ast, text, offset, results) or symbol == ':' then local parent, oop = findParent(ast, text, start) if parent then + tracy.ZoneBeginN 'completion.trySymbol' checkField(ast, '', start, offset, parent, oop, results) + tracy.ZoneEnd() end end if symbol == '(' then @@ -1673,10 +1690,15 @@ local function tryComment(ast, text, offset, results) end local function completion(uri, offset) + tracy.ZoneBeginN 'completion.getAst' local ast = files.getAst(uri) + tracy.ZoneEnd() + tracy.ZoneBeginN 'completion.getText' local text = files.getText(uri) + tracy.ZoneEnd() local results = {} clearStack() + tracy.ZoneBeginN 'completion' if ast then if getComment(ast, offset) then tryLuaDoc(ast, text, offset, results) @@ -1694,6 +1716,7 @@ local function completion(uri, offset) checkCommon(ast, word, text, offset, results) end end + tracy.ZoneEnd() if #results == 0 then return nil diff --git a/script/files.lua b/script/files.lua index 8a16edbe..fd9a55ab 100644 --- a/script/files.lua +++ b/script/files.lua @@ -103,6 +103,7 @@ function m.setText(uri, text) if not text then return end + --log.debug('setText', uri) local originUri = uri uri = getUriKey(uri) local create @@ -284,7 +285,12 @@ function m.compileAst(uri, text) if state then state.uri = uri state.ast.uri = uri + local clock = os.clock() parser:luadoc(state) + local passed = os.clock() - clock + if passed > 0.1 then + log.warn(('Parse LuaDoc of [%s] takes [%.3f] sec, size [%.3f] kb.'):format(uri, passed, #text / 1000)) + end return state else log.error(err) diff --git a/script/parser/guide.lua b/script/parser/guide.lua index 6ba7e903..ab4cbdcd 100644 --- a/script/parser/guide.lua +++ b/script/parser/guide.lua @@ -2535,9 +2535,9 @@ function m.searchSameFields(status, simple, mode) max = max + 1 status.share.count = status.share.count + 1 if status.share.count % 10000 == 0 then - if TEST then - print('####', status.share.count, osClock() - status.clock) - end + --if TEST then + -- print('####', status.share.count, osClock() - status.clock) + --end if status.interface and status.interface.pulse then status.interface.pulse() end @@ -4212,7 +4212,7 @@ function m.requestReference(obj, interface, deep) m.searchRefsAsFunction(status, obj, 'ref') if m.debugMode then - print('count:', status.share.count) + --print('count:', status.share.count) end return status.results, status.share.count diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua index 647a6bed..832cdc87 100644 --- a/script/parser/luadoc.lua +++ b/script/parser/luadoc.lua @@ -992,28 +992,43 @@ local function bindGeneric(binded) end end -local function bindDocsBetween(state, binded, bindSources, start, finish) - guide.eachSourceBetween(state.ast, start, finish, function (src) - if src.start and src.start < start then - return +local function bindDocsBetween(sources, binded, bindSources, start, finish) + -- 用二分法找到第一个 + local max = #sources + local index + local left = 1 + local right = max + for _ = 1, 1000 do + index = left + (right - left) // 2 + if index <= left then + index = left + break + elseif index >= right then + index = right + break end - if src.type == 'local' - or src.type == 'setlocal' - or src.type == 'setglobal' - or src.type == 'setfield' - or src.type == 'setmethod' - or src.type == 'setindex' - or src.type == 'tablefield' - or src.type == 'tableindex' - or src.type == 'function' - or src.type == '...' then - src.bindDocs = binded - bindSources[#bindSources+1] = src + local src = sources[index] + if src.start < start then + left = index + else + right = index end - end) + end + for i = index - 1, max do + local src = sources[i] + if src then + if src.start > finish then + break + end + if src.start >= start then + src.bindDocs = binded + bindSources[#bindSources+1] = src + end + end + end end -local function bindDoc(state, lns, binded) +local function bindDoc(sources, lns, binded) if not binded then return end @@ -1030,24 +1045,42 @@ local function bindDoc(state, lns, binded) local row = guide.positionOf(lns, lastDoc.finish) local cstart, cfinish = guide.lineRange(lns, row) local nstart, nfinish = guide.lineRange(lns, row + 1) - bindDocsBetween(state, binded, bindSources, cstart, cfinish) + bindDocsBetween(sources, binded, bindSources, cstart, cfinish) if #bindSources == 0 then - bindDocsBetween(state, binded, bindSources, nstart, nfinish) + bindDocsBetween(sources, binded, bindSources, nstart, nfinish) end end local function bindDocs(state) local lns = lines(nil, state.lua) + local sources = {} + guide.eachSource(state.ast, function (src) + if src.type == 'local' + or src.type == 'setlocal' + or src.type == 'setglobal' + or src.type == 'setfield' + or src.type == 'setmethod' + or src.type == 'setindex' + or src.type == 'tablefield' + or src.type == 'tableindex' + or src.type == 'function' + or src.type == '...' then + sources[#sources+1] = src + end + end) + table.sort(sources, function (a, b) + return a.start < b.start + end) local binded for _, doc in ipairs(state.ast.docs) do if not isNextLine(lns, binded, doc) then - bindDoc(state, lns, binded) + bindDoc(sources, lns, binded) binded = {} state.ast.docs.groups[#state.ast.docs.groups+1] = binded end binded[#binded+1] = doc end - bindDoc(state, lns, binded) + bindDoc(sources, lns, binded) end return function (_, state) diff --git a/script/plugin.lua b/script/plugin.lua index c0d0ce14..dfe18b98 100644 --- a/script/plugin.lua +++ b/script/plugin.lua @@ -13,7 +13,9 @@ function m.dispatch(event, ...) if type(method) ~= 'function' then return false end + tracy.ZoneBeginN('plugin dispatch:' .. event) local suc, res1, res2 = xpcall(method, log.error, ...) + tracy.ZoneEnd() if suc then return true, res1, res2 end diff --git a/script/provider/provider.lua b/script/provider/provider.lua index 3c6f19ca..010bc24e 100644 --- a/script/provider/provider.lua +++ b/script/provider/provider.lua @@ -353,6 +353,7 @@ end) proto.on('textDocument/completion', function (params) --log.info(util.dump(params)) local core = require 'core.completion' + --log.debug('textDocument/completion') --log.debug('completion:', params.context and params.context.triggerKind, params.context and params.context.triggerCharacter) local uri = params.textDocument.uri if not files.exists(uri) then diff --git a/script/vm/getGlobals.lua b/script/vm/getGlobals.lua index 8cec1b07..fcaffdf7 100644 --- a/script/vm/getGlobals.lua +++ b/script/vm/getGlobals.lua @@ -238,5 +238,3 @@ files.watch(function (ev, uri) end end end) - -require 'tracy'.enable() diff --git a/test/full/example.lua b/test/full/example.lua index 4f6090ee..a7df10db 100644 --- a/test/full/example.lua +++ b/test/full/example.lua @@ -3,6 +3,8 @@ local parser = require 'parser' local files = require 'files' local diag = require 'core.diagnostics' local config = require 'config' +local fs = require 'bee.filesystem' +local luadoc = require "parser.luadoc" -- 临时 local function testIfExit(path) @@ -16,23 +18,29 @@ local function testIfExit(path) local need local parseClock = 0 local compileClock = 0 + local luadocClock = 0 local total for i = 1, max do vm = TEST(buf) + local luadocStart = os.clock() + luadoc(nil, vm) + local luadocPassed = os.clock() - luadocStart local passed = os.clock() - clock - parseClock = parseClock + vm.parseClock + parseClock = parseClock + vm.parseClock compileClock = compileClock + vm.compileClock + luadocClock = luadocClock + luadocPassed if passed >= 1.0 or i == max then need = passed / i total = i break end end - print(('基准编译测试[%s]单次耗时:%.10f(解析:%.10f, 编译:%.10f)'):format( + print(('基准编译测试[%s]单次耗时:%.10f(解析:%.10f, 编译:%.10f, LuaDoc: %.10f)'):format( path:filename():string(), need, parseClock / total, - compileClock / total + compileClock / total, + luadocClock / total )) local clock = os.clock() @@ -58,3 +66,4 @@ require 'tracy' .enable() testIfExit(ROOT / 'test' / 'example' / 'vm.txt') testIfExit(ROOT / 'test' / 'example' / 'largeGlobal.txt') testIfExit(ROOT / 'test' / 'example' / 'guide.txt') +testIfExit(fs.path [[D:\github\test\ECObject.lua]]) |