Refactor lines command (#11685)

# Description
This PR uses `str::lines` to simplify the `lines` command (and one other
section of code). This has two main benefits:
1. We no longer need to use regex to split on lines, as `str::lines`
splits on `\r\n` or `\n`.
2. We no longer need to handle blank empty lines at the end. E.g.,
`str::lines` results in `["text"]` for both `"test\n"` and `"text"`.

These changes give a slight boost to performance for the following
benchmarks:
1. lines of `Value::String`:
    ```nushell
    let data = open Cargo.lock
    1..10000 | each { $data | timeit { lines } } | math avg 
    ```
    current main: 392µs
    this PR: 270µs
2. lines of external stream:
    ```nushell
    1..10000 | each { open Cargo.lock | timeit { lines } } | math avg 
    ```
    current main: 794µs
    this PR: 489µs
This commit is contained in:
Ian Manske
2024-01-30 21:56:19 +00:00
committed by GitHub
parent c371d1a535
commit cf9813cbf8
2 changed files with 59 additions and 117 deletions

View File

@@ -4,7 +4,6 @@
use std::fmt::{Display, LowerExp};
use std::io;
use std::io::{BufRead, BufReader};
use std::num::FpCategory;
use super::error::{Error, ErrorCode, Result};
@@ -1034,20 +1033,7 @@ where
T: ser::Serialize,
{
let vec = to_vec(value)?;
let string = remove_json_whitespace(vec);
Ok(string)
}
fn remove_json_whitespace(v: Vec<u8>) -> String {
let reader = BufReader::new(&v[..]);
let mut output = String::new();
for line in reader.lines() {
match line {
Ok(line) => output.push_str(line.trim().trim_end()),
_ => {
eprintln!("Error removing JSON whitespace");
}
}
}
output
let string = String::from_utf8(vec)?;
let output = string.lines().map(str::trim).collect();
Ok(output)
}