Skip to content

perf: replace O(n) queue with index pointer in find_solutions_broad#316

Open
Rival wants to merge 3 commits into
seblyng:mainfrom
Rival:fix/bfs-queue-performance
Open

perf: replace O(n) queue with index pointer in find_solutions_broad#316
Rival wants to merge 3 commits into
seblyng:mainfrom
Rival:fix/bfs-queue-performance

Conversation

@Rival

@Rival Rival commented Feb 22, 2026

Copy link
Copy Markdown
Contributor

Summary

find_solutions_broad uses BFS to traverse the directory tree. The queue was implemented by calling table.remove(dirs, 1) on each iteration, which shifts all remaining elements left — making the overall traversal O(n²) in the number of directories visited.

Before:

while #dirs > 0 do
    local dir = table.remove(dirs, 1)  -- O(n) shift each time
    ...
end

After:

local head = 1
while head <= #dirs do
    local dir = dirs[head]
    head = head + 1  -- O(1)
    ...
end

This is the standard index-pointer pattern for queues in Lua (no built-in deque). The traversal is now O(n) overall. For typical projects the difference is small, but for monorepos or broad searches over deep directory trees it avoids unnecessary work.

🤖 Generated with Claude Code

- Track initialization start time per client in store.lua using
  vim.uv.now() (monotonic milliseconds) when solution/open is sent

- On workspace/projectInitializationComplete, show a two-line
  notification with the solution name (filename without extension)
  and elapsed time in seconds, e.g.:
    Panda_Unity6_2
    initialization complete in 14.3 sec

- Guard the notification with a per-client-id flag so that if Roslyn
  sends projectInitializationComplete more than once (observed with
  some Unity solutions), only the first occurrence triggers the
  notification. diagnostics.refresh() and the RoslynInitialized
  autocmd still fire on every event.

- Simplify the "Initializing" notification to two lines:
    Initializing
    {SolutionName}
  since "roslyn.nvim" is already shown in the notification title.
- Replace `vim.loop` with `vim.uv` in commands.lua (3 occurrences).
  `vim.loop` was deprecated in Neovim 0.10 in favour of `vim.uv`.
  `health.lua` already used `vim.uv` correctly — this makes the
  codebase consistent.

- Fix Neovim version check in health.lua to handle Neovim >= 1.0:
  `v.major == 0 and v.minor >= 11` would incorrectly report an error
  once Neovim 1.0 is released. Changed to
  `v.major > 0 or (v.major == 0 and v.minor >= 11)`.
`table.remove(t, 1)` shifts all remaining elements on each iteration,
making the BFS O(n²) in the number of directories visited. Replace with
a `head` index pointer that advances through the table, keeping the
traversal O(n) overall.
@seblyng

seblyng commented Feb 22, 2026

Copy link
Copy Markdown
Owner

A lot of noise with other commits than what the PR description says

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants