nushell/crates/nu-command/src
Reilly Wood 3b5172a8fa
LazyRecord (#7619)
This is an attempt to implement a new `Value::LazyRecord` variant for
performance reasons.

`LazyRecord` is like a regular `Record`, but it's possible to access
individual columns without evaluating other columns. I've implemented
`LazyRecord` for the special `$nu` variable; accessing `$nu` is
relatively slow because of all the information in `scope`, and [`$nu`
accounts for about 2/3 of Nu's startup time on
Linux](https://github.com/nushell/nushell/issues/6677#issuecomment-1364618122).

### Benchmarks

I ran some benchmarks on my desktop (Linux, 12900K) and the results are
very pleasing.

Nu's time to start up and run a command (`cargo build --release;
hyperfine 'target/release/nu -c "echo \"Hello, world!\""' --shell=none
--warmup 10`) goes from **8.8ms to 3.2ms, about 2.8x faster**.

Tests are also much faster! Running `cargo nextest` (with our very slow
`proptest` tests disabled) goes from **7.2s to 4.4s (1.6x faster)**,
because most tests involve launching a new instance of Nu.

### Design (updated)

I've added a new `LazyRecord` trait and added a `Value` variant wrapping
those trait objects, much like `CustomValue`. `LazyRecord`
implementations must implement these 2 functions:

```rust
// All column names
fn column_names(&self) -> Vec<&'static str>;

// Get 1 specific column value
fn get_column_value(&self, column: &str) -> Result<Value, ShellError>;
 ```

### Serializability

`Value` variants must implement `Serializable` and `Deserializable`, which poses some problems because I want to use unserializable things like `EngineState` in `LazyRecord`s. To work around this, I basically lie to the type system:

1. Add `#[typetag::serde(tag = "type")]` to `LazyRecord` to make it serializable
2. Any unserializable fields in `LazyRecord` implementations get marked with `#[serde(skip)]`
3. At the point where a `LazyRecord` normally would get serialized and sent to a plugin, I instead collect it into a regular `Value::Record` (which can be serialized)
2023-01-18 19:27:26 -08:00
..
bits Further cleanup of Span::test_data usage + span fixes (#7595) 2022-12-24 07:41:57 -06:00
bytes Fix typos and use more idiomatic assertions (#7755) 2023-01-15 15:03:32 +13:00
charting Fix typos by codespell (#7600) 2022-12-26 02:31:26 -05:00
conversions Further cleanup of Span::test_data usage + span fixes (#7595) 2022-12-24 07:41:57 -06:00
core_commands Continue and Break on Try/Catch (#7683) 2023-01-05 21:41:51 +01:00
database LazyRecord (#7619) 2023-01-18 19:27:26 -08:00
dataframe update sqlparser dependency (#7772) 2023-01-15 21:30:39 -06:00
date Add extra_usage messages for subcommand-only commands (#7594) 2022-12-24 07:16:29 -06:00
deprecated Remove math eval command (#7284) 2023-01-04 23:50:18 +01:00
env Fix an example of env command (#7603) 2022-12-26 16:40:34 +08:00
experimental Change instances of Value::string("foo", Span::test_data()) to Value::test_string("foo") (#7592) 2022-12-24 10:25:38 +01:00
filesystem Check all user groups. (#7775) 2023-01-17 19:49:54 -06:00
filters LazyRecord (#7619) 2023-01-18 19:27:26 -08:00
formats LazyRecord (#7619) 2023-01-18 19:27:26 -08:00
generators Further cleanup of Span::test_data usage + span fixes (#7595) 2022-12-24 07:41:57 -06:00
hash Add extra_usage messages for subcommand-only commands (#7594) 2022-12-24 07:16:29 -06:00
math Fix typos and use more idiomatic assertions (#7755) 2023-01-15 15:03:32 +13:00
misc Add more input/output type annotations (#7532) 2022-12-21 20:20:46 +01:00
network Rename to url command to url build-query (#7702) 2023-01-15 10:16:29 -08:00
path spanned error on path exists command (#7717) 2023-01-12 06:56:39 -06:00
platform add magenta to ansi command as synonym for purple (#7785) 2023-01-17 19:50:55 -06:00
random Add search terms in random and expression categories (#7736) 2023-01-12 14:01:40 +01:00
shells Add more input/output type annotations (#7532) 2022-12-21 20:20:46 +01:00
strings Fix typos and use more idiomatic assertions (#7755) 2023-01-15 15:03:32 +13:00
system Trim quotes when shelling out to cmd.exe (#7740) 2023-01-13 11:00:30 -08:00
viewers LazyRecord (#7619) 2023-01-18 19:27:26 -08:00
default_context.rs Rename to url command to url build-query (#7702) 2023-01-15 10:16:29 -08:00
example_test.rs Make stream info visible to users in describe (#7589) 2023-01-03 21:08:05 -08:00
input_handler.rs Standardise the use of ShellError::UnsupportedInput and ShellError::TypeMismatch and add spans to every instance of the former (#7217) 2022-12-23 01:48:53 -05:00
lib.rs Progress bar Implementation (#7661) 2023-01-10 20:57:48 -05:00
progress_bar.rs Progress bar Implementation (#7661) 2023-01-10 20:57:48 -05:00
sort_utils.rs Further cleanup of Span::test_data usage + span fixes (#7595) 2022-12-24 07:41:57 -06:00