Hopefully speedup startup (#8913)

# Description

Trying a few different things to hopefully speedup startup a bit. I'm
seeing some improvement on my box for the profiles I have, but the data
I'm seeing is noisy.

- Remove allocations in a few places where we created vec's but could
use iterators
- Pre-allocate space for blocks based on the lite block
- Removed a few extra clones

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass
- `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the
standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
This commit is contained in:
JT
2023-04-18 20:19:08 +12:00
committed by GitHub
parent 06996d8c7f
commit 32f098d91d
6 changed files with 236 additions and 245 deletions

View File

@ -232,6 +232,17 @@ pub fn parse_for(working_set: &mut StateWorkingSet, spans: &[Span]) -> Expressio
let decl = working_set.get_decl(decl_id);
let sig = decl.signature();
let starting_error_count = working_set.parse_errors.len();
check_call(working_set, call_span, &sig, &call);
if starting_error_count != working_set.parse_errors.len() || call.has_flag("help") {
return Expression {
expr: Expr::Call(call),
span: call_span,
ty: output,
custom_completion: None,
};
}
// Let's get our block and make sure it has the right signature
if let Some(arg) = call.positional_nth(2) {
match arg {
@ -245,23 +256,12 @@ pub fn parse_for(working_set: &mut StateWorkingSet, spans: &[Span]) -> Expressio
} => {
let block = working_set.get_block_mut(*block_id);
block.signature = Box::new(sig.clone());
block.signature = Box::new(sig);
}
_ => {}
}
}
let starting_error_count = working_set.parse_errors.len();
check_call(working_set, call_span, &sig, &call);
if starting_error_count != working_set.parse_errors.len() || call.has_flag("help") {
return Expression {
expr: Expr::Call(call),
span: call_span,
ty: output,
custom_completion: None,
};
}
(call, call_span)
}
};
@ -1403,85 +1403,87 @@ pub fn parse_module_block(
let mut module = Module::from_span(module_name.to_vec(), span);
let block: Block = output
.block
.iter()
.map(|pipeline| {
if pipeline.commands.len() == 1 {
match &pipeline.commands[0] {
LiteElement::Command(_, command) => {
let name = working_set.get_span_contents(command.parts[0]);
let mut block = Block::new_with_capacity(output.block.len());
match name {
b"def" | b"def-env" => {
parse_def(
working_set,
command,
None, // using commands named as the module locally is OK
)
}
b"extern" => parse_extern(working_set, command, None),
b"alias" => {
parse_alias(
working_set,
command,
None, // using aliases named as the module locally is OK
)
}
b"use" => {
let (pipeline, _) = parse_use(working_set, &command.parts);
for pipeline in output.block.iter() {
if pipeline.commands.len() == 1 {
match &pipeline.commands[0] {
LiteElement::Command(_, command) => {
let name = working_set.get_span_contents(command.parts[0]);
pipeline
}
b"export" => {
let (pipe, exportables) =
parse_export_in_module(working_set, command, module_name);
match name {
b"def" | b"def-env" => {
block.pipelines.push(parse_def(
working_set,
command,
None, // using commands named as the module locally is OK
))
}
b"extern" => block
.pipelines
.push(parse_extern(working_set, command, None)),
b"alias" => {
block.pipelines.push(parse_alias(
working_set,
command,
None, // using aliases named as the module locally is OK
))
}
b"use" => {
let (pipeline, _) = parse_use(working_set, &command.parts);
for exportable in exportables {
match exportable {
Exportable::Decl { name, id } => {
if &name == b"main" {
module.main = Some(id);
} else {
module.add_decl(name, id);
}
block.pipelines.push(pipeline)
}
b"export" => {
let (pipe, exportables) =
parse_export_in_module(working_set, command, module_name);
for exportable in exportables {
match exportable {
Exportable::Decl { name, id } => {
if &name == b"main" {
module.main = Some(id);
} else {
module.add_decl(name, id);
}
}
}
pipe
}
b"export-env" => {
let (pipe, maybe_env_block) =
parse_export_env(working_set, &command.parts);
if let Some(block_id) = maybe_env_block {
module.add_env_block(block_id);
}
block.pipelines.push(pipe)
}
b"export-env" => {
let (pipe, maybe_env_block) =
parse_export_env(working_set, &command.parts);
pipe
if let Some(block_id) = maybe_env_block {
module.add_env_block(block_id);
}
_ => {
working_set.error(ParseError::ExpectedKeyword(
"def or export keyword".into(),
command.parts[0],
));
garbage_pipeline(&command.parts)
}
block.pipelines.push(pipe)
}
_ => {
working_set.error(ParseError::ExpectedKeyword(
"def or export keyword".into(),
command.parts[0],
));
block.pipelines.push(garbage_pipeline(&command.parts))
}
}
LiteElement::Redirection(_, _, command) => garbage_pipeline(&command.parts),
LiteElement::SeparateRedirection {
out: (_, command), ..
} => garbage_pipeline(&command.parts),
}
} else {
working_set.error(ParseError::Expected("not a pipeline".into(), span));
garbage_pipeline(&[span])
LiteElement::Redirection(_, _, command) => {
block.pipelines.push(garbage_pipeline(&command.parts))
}
LiteElement::SeparateRedirection {
out: (_, command), ..
} => block.pipelines.push(garbage_pipeline(&command.parts)),
}
})
.into();
} else {
working_set.error(ParseError::Expected("not a pipeline".into(), span));
block.pipelines.push(garbage_pipeline(&[span]))
}
}
working_set.exit_scope();