perf(picker): process process chunks async by queing them from the callbacks

This commit is contained in:
Folke Lemaitre 2025-01-14 17:48:57 +01:00
parent b6aee37691
commit ad792eb908
No known key found for this signature in database
GPG key ID: 41F8B1FBACAE2040
4 changed files with 24 additions and 10 deletions

View file

@ -10,7 +10,7 @@ M.__index = M
---@alias snacks.picker.finder fun(opts:snacks.picker.Config, filter:snacks.picker.Filter): (snacks.picker.finder.Item[] | fun(cb:async fun(item:snacks.picker.finder.Item)))
local YIELD_FIND = 5 -- ms
local YIELD_FIND = 1 -- ms
---@param find snacks.picker.finder
function M.new(find)

View file

@ -2,7 +2,7 @@ local Async = require("snacks.picker.util.async")
local Finder = require("snacks.picker.core.finder")
local uv = vim.uv or vim.loop
Async.BUDGET = 20
Async.BUDGET = 10
---@class snacks.Picker
---@field opts snacks.picker.Config

View file

@ -4,6 +4,7 @@ local Buffer = require("string.buffer")
local M = {}
local uv = vim.uv or vim.loop
M.USE_QUEUE = true
---@class snacks.picker.proc.Config: snacks.picker.Config
---@field cmd string
@ -89,13 +90,24 @@ function M.proc(opts)
end
end
local queue = require("snacks.picker.util.queue").new()
stdout:read_start(function(err, data)
assert(not err, err)
process(data)
if M.USE_QUEUE then
queue:push(data)
self:resume()
else
process(data)
end
end)
while not handle:is_closing() do
self:suspend()
while not (handle:is_closing() and queue:empty()) do
if queue:empty() then
self:suspend()
else
process(queue:pop())
end
end
end
end

View file

@ -278,13 +278,15 @@ function M.yielder(ms)
if not coroutine.running() then
return function() end
end
ms = ms or 5
local start = uv.hrtime()
local ns, count, start = (ms or 5) * 1e6, 0, uv.hrtime()
---@async
return function()
if uv.hrtime() - start > ms * 1e6 then
M.yield()
start = uv.hrtime()
count = count + 1
if count % 100 == 0 then
if uv.hrtime() - start > ns then
M.yield()
start = uv.hrtime()
end
end
end
end