1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 12:07:46 +00:00

ls: Add extend_pad_left/right functions that operate on Vec<u8>

Saves another ~7% performance.
This commit is contained in:
Nicolas Boichat 2025-04-19 20:47:47 +02:00
parent 8b9960f093
commit 4212385f76

View file

@ -5,6 +5,7 @@
// spell-checker:ignore (ToDO) somegroup nlink tabsize dired subdired dtype colorterm stringly // spell-checker:ignore (ToDO) somegroup nlink tabsize dired subdired dtype colorterm stringly
use std::iter;
#[cfg(windows)] #[cfg(windows)]
use std::os::windows::fs::MetadataExt; use std::os::windows::fs::MetadataExt;
use std::{cell::OnceCell, num::IntErrorKind}; use std::{cell::OnceCell, num::IntErrorKind};
@ -2420,12 +2421,33 @@ fn display_dir_entry_size(
} }
} }
fn pad_left(string: &str, count: usize) -> String { // A simple, performant, ExtendPad trait to add a string to a Vec<u8>, padding with spaces
format!("{string:>count$}") // on the left or right, without making additional copies, or using formatting functions.
trait ExtendPad {
fn extend_pad_left(&mut self, string: &str, count: usize);
fn extend_pad_right(&mut self, string: &str, count: usize);
} }
fn pad_right(string: &str, count: usize) -> String { impl ExtendPad for Vec<u8> {
format!("{string:<count$}") fn extend_pad_left(&mut self, string: &str, count: usize) {
if string.len() < count {
self.extend(iter::repeat_n(b' ', count - string.len()));
}
self.extend(string.as_bytes());
}
fn extend_pad_right(&mut self, string: &str, count: usize) {
self.extend(string.as_bytes());
if string.len() < count {
self.extend(iter::repeat_n(b' ', count - string.len()));
}
}
}
// TODO: Consider converting callers to use ExtendPad instead, as it avoids
// additional copies.
fn pad_left(string: &str, count: usize) -> String {
format!("{string:>count$}")
} }
fn return_total( fn return_total(
@ -2784,61 +2806,55 @@ fn display_item_long(
output_display.extend(b"+"); output_display.extend(b"+");
} }
output_display.extend(b" "); output_display.extend(b" ");
output_display.extend(pad_left(&display_symlink_count(md), padding.link_count).as_bytes()); output_display.extend_pad_left(&display_symlink_count(md), padding.link_count);
if config.long.owner { if config.long.owner {
output_display.extend(b" "); output_display.extend(b" ");
output_display.extend(pad_right(&display_uname(md, config), padding.uname).as_bytes()); output_display.extend_pad_right(&display_uname(md, config), padding.uname);
} }
if config.long.group { if config.long.group {
output_display.extend(b" "); output_display.extend(b" ");
output_display.extend(pad_right(&display_group(md, config), padding.group).as_bytes()); output_display.extend_pad_right(&display_group(md, config), padding.group);
} }
if config.context { if config.context {
output_display.extend(b" "); output_display.extend(b" ");
output_display.extend(pad_right(&item.security_context, padding.context).as_bytes()); output_display.extend_pad_right(&item.security_context, padding.context);
} }
// Author is only different from owner on GNU/Hurd, so we reuse // Author is only different from owner on GNU/Hurd, so we reuse
// the owner, since GNU/Hurd is not currently supported by Rust. // the owner, since GNU/Hurd is not currently supported by Rust.
if config.long.author { if config.long.author {
output_display.extend(b" "); output_display.extend(b" ");
output_display.extend(pad_right(&display_uname(md, config), padding.uname).as_bytes()); output_display.extend_pad_right(&display_uname(md, config), padding.uname);
} }
match display_len_or_rdev(md, config) { match display_len_or_rdev(md, config) {
SizeOrDeviceId::Size(size) => { SizeOrDeviceId::Size(size) => {
output_display.extend(b" "); output_display.extend(b" ");
output_display.extend(pad_left(&size, padding.size).as_bytes()); output_display.extend_pad_left(&size, padding.size);
} }
SizeOrDeviceId::Device(major, minor) => { SizeOrDeviceId::Device(major, minor) => {
output_display.extend(b" "); output_display.extend(b" ");
output_display.extend( output_display.extend_pad_left(
pad_left( &major,
&major, #[cfg(not(unix))]
#[cfg(not(unix))] 0usize,
0usize, #[cfg(unix)]
#[cfg(unix)] padding.major.max(
padding.major.max( padding
padding .size
.size .saturating_sub(padding.minor.saturating_add(2usize)),
.saturating_sub(padding.minor.saturating_add(2usize)), ),
),
)
.as_bytes(),
); );
output_display.extend(b", "); output_display.extend(b", ");
output_display.extend( output_display.extend_pad_left(
pad_left( &minor,
&minor, #[cfg(not(unix))]
#[cfg(not(unix))] 0usize,
0usize, #[cfg(unix)]
#[cfg(unix)] padding.minor,
padding.minor,
)
.as_bytes(),
); );
} }
}; };
@ -2917,28 +2933,28 @@ fn display_item_long(
output_display.extend(b"."); output_display.extend(b".");
} }
output_display.extend(b" "); output_display.extend(b" ");
output_display.extend(pad_left("?", padding.link_count).as_bytes()); output_display.extend_pad_left("?", padding.link_count);
if config.long.owner { if config.long.owner {
output_display.extend(b" "); output_display.extend(b" ");
output_display.extend(pad_right("?", padding.uname).as_bytes()); output_display.extend_pad_right("?", padding.uname);
} }
if config.long.group { if config.long.group {
output_display.extend(b" "); output_display.extend(b" ");
output_display.extend(pad_right("?", padding.group).as_bytes()); output_display.extend_pad_right("?", padding.group);
} }
if config.context { if config.context {
output_display.extend(b" "); output_display.extend(b" ");
output_display.extend(pad_right(&item.security_context, padding.context).as_bytes()); output_display.extend_pad_right(&item.security_context, padding.context);
} }
// Author is only different from owner on GNU/Hurd, so we reuse // Author is only different from owner on GNU/Hurd, so we reuse
// the owner, since GNU/Hurd is not currently supported by Rust. // the owner, since GNU/Hurd is not currently supported by Rust.
if config.long.author { if config.long.author {
output_display.extend(b" "); output_display.extend(b" ");
output_display.extend(pad_right("?", padding.uname).as_bytes()); output_display.extend_pad_right("?", padding.uname);
} }
let displayed_item = display_item_name( let displayed_item = display_item_name(
@ -2953,9 +2969,9 @@ fn display_item_long(
let date_len = 12; let date_len = 12;
output_display.extend(b" "); output_display.extend(b" ");
output_display.extend(pad_left("?", padding.size).as_bytes()); output_display.extend_pad_left("?", padding.size);
output_display.extend(b" "); output_display.extend(b" ");
output_display.extend(pad_left("?", date_len).as_bytes()); output_display.extend_pad_left("?", date_len);
output_display.extend(b" "); output_display.extend(b" ");
if config.dired { if config.dired {