perf(lua): memoize key_fn results #39568

Problem:
When using `vim.list.unique` or `vim.list.bisect`, if the `key` function is
complex, it can degrade performance, because it is invoked on every comparison

Solution:
The `key` interface convention is designed specifically to address this issue;
performance can be improved by memoizing its results.

Also added the shorthand use of the field name string as the key.
This commit is contained in:
Yi Ming
2026-05-06 05:04:11 +08:00
committed by GitHub
parent ed194b99ac
commit 97de5f145a
4 changed files with 82 additions and 30 deletions

View File

@@ -23,6 +23,8 @@ describe('vim.list', function()
return x[1]
end)
)
eq({ { id = 1 }, { id = 2 } }, vim.list.unique({ { id = 1 }, { id = 2 }, { id = 1 } }, 'id'))
end)
--- Generate a list like { 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, ...}.
@@ -52,6 +54,9 @@ describe('vim.list', function()
local target = math.random(num)
eq(vim.list.bisect(list, target, { bound = 'lower' }), index(target - 1) + 1)
eq(vim.list.bisect(list, num + 1, { bound = 'lower' }), index(num) + 1)
local dict_list = { { value = 1 }, { value = 2 }, { value = 2 }, { value = 3 } }
eq(2, vim.list.bisect(dict_list, { value = 2 }, { key = 'value', bound = 'lower' }))
end)
it("vim.list.bisect(..., bound = { 'upper' })", function()
@@ -61,5 +66,8 @@ describe('vim.list', function()
local target = math.random(num)
eq(vim.list.bisect(list, target, { bound = 'upper' }), index(target) + 1)
eq(vim.list.bisect(list, num + 1, { bound = 'upper' }), index(num) + 1)
local dict_list = { { value = 1 }, { value = 2 }, { value = 2 }, { value = 3 } }
eq(4, vim.list.bisect(dict_list, { value = 2 }, { key = 'value', bound = 'upper' }))
end)
end)