Skip to content

Commit

Permalink
perf(lua): optimize vim.deep_equal neovim#15236
Browse files Browse the repository at this point in the history
By remembering the keys already compared in repeating a comparison is
avoided. Thanks: https://stackoverflow.com/a/32660766
  • Loading branch information
muniter committed Sep 10, 2021
1 parent 3b3dbcf commit 4b452d4
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
12 changes: 11 additions & 1 deletion runtime/doc/lua.txt
Expand Up @@ -1268,7 +1268,17 @@ schedule_wrap({cb}) *vim.schedule_wrap()*


deep_equal({a}, {b}) *vim.deep_equal()*
TODO: Documentation
Deep compare values for equality

Tables are compared recursively unless they both provide the `eq` methamethod.
All other types are compared using the equality `==` operator.

Parameters: ~
{a} first value
{b} second value

Return: ~
`true` if values are equals, else `false` .

deepcopy({orig}) *vim.deepcopy()*
Returns a deep copy of the given object. Non-table objects are
Expand Down
11 changes: 8 additions & 3 deletions runtime/lua/vim/shared.lua
Expand Up @@ -267,18 +267,23 @@ function vim.tbl_deep_extend(behavior, ...)
end

--- Deep compare values for equality
---
--- Tables are compared recursively unless they both provide the `eq` methamethod.
--- All other types are compared using the equality `==` operator.
---@param a first value
---@param b second value
---@returns `true` if values are equals, else `false`.
function vim.deep_equal(a, b)
if a == b then return true end
if type(a) ~= type(b) then return false end
if type(a) == 'table' then
-- TODO improve this algorithm's performance.
for k, v in pairs(a) do
if not vim.deep_equal(v, b[k]) then
return false
end
end
for k, v in pairs(b) do
if not vim.deep_equal(v, a[k]) then
for k, _ in pairs(b) do
if a[k] == nil then
return false
end
end
Expand Down

0 comments on commit 4b452d4

Please sign in to comment.