diff options
author | Lewis Russell <lewis6991@gmail.com> | 2023-06-03 11:06:10 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-03 12:06:10 +0200 |
commit | 40db569014471deb5bd17860be00d6833387be79 (patch) | |
tree | 227de8c8e7cfad463c233b7a4209c88a09911637 /runtime/lua/vim/iter.lua | |
parent | 2db719f6c2b677fcbc197b02fe52764a851523b2 (diff) | |
download | rneovim-40db569014471deb5bd17860be00d6833387be79.tar.gz rneovim-40db569014471deb5bd17860be00d6833387be79.tar.bz2 rneovim-40db569014471deb5bd17860be00d6833387be79.zip |
perf(iter): make ListIter.totable more efficient (#23714)
Diffstat (limited to 'runtime/lua/vim/iter.lua')
-rw-r--r-- | runtime/lua/vim/iter.lua | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/runtime/lua/vim/iter.lua b/runtime/lua/vim/iter.lua index 56012e9b9f..0e98d0437e 100644 --- a/runtime/lua/vim/iter.lua +++ b/runtime/lua/vim/iter.lua @@ -66,7 +66,7 @@ end ---@class ListIter : Iter ---@field _table table Underlying table data ---@field _head number Index to the front of a table iterator ----@field _tail number Index to the end of a table iterator +---@field _tail number Index to the end of a table iterator (exclusive) local ListIter = {} ListIter.__index = setmetatable(ListIter, Iter) ListIter.__call = function(self) @@ -321,17 +321,33 @@ end ---@private function ListIter.totable(self) - if self._head == 1 and self._tail == #self._table + 1 and self.next == ListIter.next then - -- Sanitize packed table values - if getmetatable(self._table[1]) == packedmt then - for i = 1, #self._table do - self._table[i] = sanitize(self._table[i]) - end + if self.next ~= ListIter.next or self._head >= self._tail then + return Iter.totable(self) + end + + local needs_sanitize = getmetatable(self._table[1]) == packedmt + + -- Reindex and sanitize. + local len = self._tail - self._head + + if needs_sanitize then + for i = 1, len do + self._table[i] = sanitize(self._table[self._head - 1 + i]) + end + else + for i = 1, len do + self._table[i] = self._table[self._head - 1 + i] end - return self._table end - return Iter.totable(self) + for i = len + 1, table.maxn(self._table) do + self._table[i] = nil + end + + self._head = 1 + self._tail = len + 1 + + return self._table end --- Fold an iterator or table into a single value. |