summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2021-01-05 21:23:38 +0800
committer最萌小汐 <sumneko@hotmail.com>2021-01-05 21:23:38 +0800
commitb62eba6d93fc026873d29dc865cd3f745cb403fd (patch)
tree9ddb1bb78113f8201e634a2e3c305f4e0985d02f
parenta6cfc1162c24e1621076bc96b36768873bbaf9d4 (diff)
downloadlua-language-server-b62eba6d93fc026873d29dc865cd3f745cb403fd.zip
improve performance
-rw-r--r--script/core/completion.lua23
-rw-r--r--script/files.lua6
-rw-r--r--script/parser/guide.lua8
-rw-r--r--script/parser/luadoc.lua77
-rw-r--r--script/plugin.lua2
-rw-r--r--script/provider/provider.lua1
-rw-r--r--script/vm/getGlobals.lua2
-rw-r--r--test/full/example.lua15
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]])