diff options
| author | Yi Ming <ofseed@foxmail.com> | 2026-04-25 12:52:08 +0800 |
|---|---|---|
| committer | Yi Ming <ofseed@foxmail.com> | 2026-04-25 19:02:06 +0800 |
| commit | bbd0fdd36dcd684e09836ff41517e0e7ea6d802e (patch) | |
| tree | 7e65a86ed84fe5147607f8d5cf7fae61817db081 /runtime/lua/vim/lsp | |
| parent | 1235c956ca6d889eeeae944335ea09a9f2047392 (diff) | |
| download | rneovim-bbd0fdd36dcd684e09836ff41517e0e7ea6d802e.tar.gz rneovim-bbd0fdd36dcd684e09836ff41517e0e7ea6d802e.tar.bz2 rneovim-bbd0fdd36dcd684e09836ff41517e0e7ea6d802e.zip | |
perf(lsp): avoid unnecessary string allocations when parsing content-length
Diffstat (limited to 'runtime/lua/vim/lsp')
| -rw-r--r-- | runtime/lua/vim/lsp/rpc.lua | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/runtime/lua/vim/lsp/rpc.lua b/runtime/lua/vim/lsp/rpc.lua index 7d85be89c9..6739073cd3 100644 --- a/runtime/lua/vim/lsp/rpc.lua +++ b/runtime/lua/vim/lsp/rpc.lua @@ -191,22 +191,30 @@ local default_dispatchers = { } --- @async -local function request_parser_loop() - local buf = strbuffer.new() +local function parse_content_length() + local strbuf = strbuffer.new() while true do - local msg = buf:tostring() - local header_end = msg:find('\r\n\r\n', 1, true) - if header_end then - local header = buf:get(header_end + 1) - buf:skip(2) -- skip past header boundary + local header_len ---@type integer? + local ptr, len = strbuf:ref() + for i = 0, len - 4 do + -- Find the header boundary "\r\n\r\n" + -- (compare bytes instead of string.find(), to avoid a string alloc). + if ptr[i] == 13 and ptr[i + 1] == 10 and ptr[i + 2] == 13 and ptr[i + 3] == 10 then + header_len = i + 2 + break + end + end + if header_len then + local header = strbuf:get(header_len) + strbuf:skip(2) -- skip past header boundary local content_length = get_content_length(header) - while strbuffer.len(buf) < content_length do - buf:put(coroutine.yield()) + while strbuffer.len(strbuf) < content_length do + strbuf:put(coroutine.yield()) end - local body = buf:get(content_length) - buf:put(coroutine.yield(body)) + local body = strbuf:get(content_length) + strbuf:put(coroutine.yield(body)) else - buf:put(coroutine.yield()) + strbuf:put(coroutine.yield()) end end end @@ -218,7 +226,7 @@ end function M.create_read_loop(handle_body, on_exit, on_error) on_exit = on_exit or function() end on_error = on_error or function() end - local co = coroutine.create(request_parser_loop) + local co = coroutine.create(parse_content_length) coroutine.resume(co) return function(err, chunk) if err then |