Skip to content

perf: avoid cloning list values - #18636

Merged
fdncred merged 3 commits into
nushell:mainfrom
Alb-O:perf/cow-list-values
Jul 22, 2026
Merged

fdncred merged 3 commits into
nushell:mainfrom
Alb-O:perf/cow-list-values

Conversation

@Alb-O

@Alb-O Alb-O commented Jul 17, 2026 •

Copy link
Copy Markdown
Contributor

Description

Store list Values in SharedCow<Vec<Value>> so clones share their backing allocation until mutation.

Use copy-on-write storage at list mutation sites and only materialize an owned Vec<Value> when an operation genuinely consumes the list. Preserve shared storage through first, last, empty-list concatenation, and no-op flattening paths.

Add tests for shared cloning and copy-on-write behavior, plus Tango benchmarks for cloning list values and loading them from the stack.

User-facing changes (Release notes)

Faster large list and table access

Large lists and tables are now much faster to read from, load from variables, and capture in closures.

Accessing a small part of a large list, such as $list.0, no longer copies the entire list each time the variable is loaded. In a 100,000-element test, 200 repeated reads improved from roughly 131 ms to 138 µs (~950x faster).

Additional notes

Tango results from 100 paired samples against current unpatched main:

Benchmark Reference Patched Change
list_value_clone_100000 668.3 µs 35.4 ns -99.995%, ~18,900x faster
stack_list_get_var_100000 649.1 µs 75.7 ns -99.988%, ~8,600x faster

Local end-to-end results for 200 repeated $list.0 reads:

List size Reference Patched Change
1,000 1.41 ms 149 µs -89.4%, 9.4x faster
10,000 12.13 ms 140 µs -98.8%, 86.8x faster
100,000 131.19 ms 138 µs -99.89%, ~950x faster

Perf is approximately constant as the list grows, removing the previous O(list length) cost from each variable load.

Store list `Value`s in `SharedCow<Vec<Value>>` so variable loads and
captures retain shared backing storage until mutation. Keep mutation
boundaries explicit and only materialize owned vectors for consuming
operations.

Preserve sharing in `first`, `last`, empty concatenation, and no-op
flattening paths. Add copy-on-write regression coverage and Tango
benchmarks for value cloning and stack variable loads.
@github-actions github-actions Bot added A:plugin-polars Work related to the polars dataframe implementation A:plugins This issue is about plugins labels Jul 17, 2026
@fdncred fdncred added notes:ready Indicates Ready for Release notes notes:perf Performance related PRs labels Jul 22, 2026
@fdncred
fdncred merged commit 0486400 into nushell:main Jul 22, 2026
14 checks passed
@fdncred

fdncred commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Thanks!

@github-actions github-actions Bot added this to the v0.115.0 milestone Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A:plugin-polars Work related to the polars dataframe implementation A:plugins This issue is about plugins notes:perf Performance related PRs notes:ready Indicates Ready for Release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants