diff options
author | Lewis Russell <lewis6991@gmail.com> | 2024-01-02 15:47:55 +0000 |
---|---|---|
committer | Lewis Russell <me@lewisr.dev> | 2024-01-03 19:17:52 +0000 |
commit | 3734519e3b4ba1bf19ca772104170b0ef776be46 (patch) | |
tree | 33ef73759201265fe99b5c0499d7f792a855aef0 /runtime/doc | |
parent | a064ed622927b4c5e30165abbe54db841359c71f (diff) | |
download | rneovim-3734519e3b4ba1bf19ca772104170b0ef776be46.tar.gz rneovim-3734519e3b4ba1bf19ca772104170b0ef776be46.tar.bz2 rneovim-3734519e3b4ba1bf19ca772104170b0ef776be46.zip |
feat(lua): add noref to deepcopy
Problem:
Currently `deepcopy` hashes every single tables it copies so it can be
reused. For tables of mostly unique items that are non recursive, this
hashing is unnecessarily expensive
Solution:
Port the `noref` argument from Vimscripts `deepcopy()`.
The below benchmark demonstrates the results for two extreme cases of
tables of different sizes. One table that uses the same table lots of
times and one with all unique tables.
| test | `noref=false` (ms) | `noref=true` (ms) |
| -------------------- | ------------------ | ----------------- |
| unique tables (50) | 6.59 | 2.62 |
| shared tables (50) | 3.24 | 6.40 |
| unique tables (2000) | 23381.48 | 2884.53 |
| shared tables (2000) | 3505.54 | 14038.80 |
The results are basically the inverse of each other where `noref` is
much more performance on tables with unique fields, and `not noref` is
more performant on tables that reuse fields.
Diffstat (limited to 'runtime/doc')
-rw-r--r-- | runtime/doc/lua.txt | 13 | ||||
-rw-r--r-- | runtime/doc/news.txt | 2 |
2 files changed, 13 insertions, 2 deletions
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index 9c9a9db175..e01e16b8f4 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -1905,15 +1905,24 @@ vim.deep_equal({a}, {b}) *vim.deep_equal()* Return: ~ (boolean) `true` if values are equals, else `false` -vim.deepcopy({orig}) *vim.deepcopy()* +vim.deepcopy({orig}, {noref}) *vim.deepcopy()* Returns a deep copy of the given object. Non-table objects are copied as in a typical Lua assignment, whereas table objects are copied recursively. Functions are naively copied, so functions in the copied table point to the same functions as those in the input table. Userdata and threads are not copied and will throw an error. + Note: `noref=true` is much more performant on tables with unique table + fields, while `noref=false` is more performant on tables that reuse table + fields. + Parameters: ~ - • {orig} (table) Table to copy + • {orig} (table) Table to copy + • {noref} (boolean|nil) When `false` (default) a contained table is + only copied once and all references point to this single + copy. When `true` every occurrence of a table results in a + new copy. This also means that a cyclic reference can cause + `deepcopy()` to fail. Return: ~ (table) Table of copied keys and (nested) values. diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 03e1989e62..d3ace5f33b 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -282,6 +282,8 @@ The following new APIs and features were added. |vim.diagnostic.get()| when only the number of diagnostics is needed, but not the diagnostics themselves. +• |vim.deepcopy()| has a `noref` argument to avoid hashing table values. + ============================================================================== CHANGED FEATURES *news-changed* |