From d99b2d6f7db1f88e353021ed55e9492a3997ed8e Mon Sep 17 00:00:00 2001 From: David Sherret Date: Mon, 9 Dec 2024 19:28:53 -0500 Subject: [PATCH] chore: reduce allocations in a few places (#27288) Probably doesn't have much impact. I didn't measure any of these, but reducing allocations should always be good. --- Cargo.lock | 14 ++++++-- Cargo.toml | 1 + cli/util/path.rs | 5 +-- cli/util/progress_bar/renderer.rs | 9 ++++-- resolvers/npm_cache/tarball_extract.rs | 5 +-- runtime/permissions/Cargo.toml | 1 + runtime/permissions/lib.rs | 45 ++++++++++++++++---------- 7 files changed, 54 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 30824206b6..26936169e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -668,6 +668,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bf2a5fb3207c12b5d208ebc145f967fea5cac41a021c37417ccc31ba40f39ee" +[[package]] +name = "capacity_builder" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c0f637033edd76ceb881faaee372868a383f0ed7a4a59e8fdf90db2502f3d3" +dependencies = [ + "itoa", +] + [[package]] name = "caseless" version = "0.2.1" @@ -2088,6 +2097,7 @@ dependencies = [ name = "deno_permissions" version = "0.41.0" dependencies = [ + "capacity_builder", "deno_core", "deno_path_util", "deno_terminal 0.2.0", @@ -4375,9 +4385,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jni-sys" diff --git a/Cargo.toml b/Cargo.toml index f8b01164ac..c3703d8c5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -108,6 +108,7 @@ boxed_error = "0.2.2" brotli = "6.0.0" bytes = "1.4.0" cache_control = "=0.2.0" +capacity_builder = "0.1.0" cbc = { version = "=0.1.2", features = ["alloc"] } # Note: Do not use the "clock" feature of chrono, as it links us to CoreFoundation on macOS. # Instead use util::time::utc_now() diff --git a/cli/util/path.rs b/cli/util/path.rs index df66b83766..de72843406 100644 --- a/cli/util/path.rs +++ b/cli/util/path.rs @@ -1,6 +1,7 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. use std::borrow::Cow; +use std::fmt::Write; use std::path::Path; use std::path::PathBuf; @@ -58,8 +59,8 @@ pub fn get_atomic_file_path(file_path: &Path) -> PathBuf { } fn gen_rand_path_component() -> String { - (0..4).fold(String::new(), |mut output, _| { - output.push_str(&format!("{:02x}", rand::random::())); + (0..4).fold(String::with_capacity(8), |mut output, _| { + write!(&mut output, "{:02x}", rand::random::()).unwrap(); output }) } diff --git a/cli/util/progress_bar/renderer.rs b/cli/util/progress_bar/renderer.rs index 6b08dada12..db3d37140f 100644 --- a/cli/util/progress_bar/renderer.rs +++ b/cli/util/progress_bar/renderer.rs @@ -1,5 +1,6 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +use std::fmt::Write; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; use std::time::Duration; @@ -81,12 +82,14 @@ impl ProgressBarRenderer for BarProgressBarRenderer { let elapsed_text = get_elapsed_text(data.duration); let mut text = String::new(); if !display_entry.message.is_empty() { - text.push_str(&format!( - "{} {}{}\n", + writeln!( + &mut text, + "{} {}{}", colors::green("Download"), display_entry.message, bytes_text, - )); + ) + .unwrap(); } text.push_str(&elapsed_text); let max_width = (data.terminal_width as i32 - 5).clamp(10, 75) as usize; diff --git a/resolvers/npm_cache/tarball_extract.rs b/resolvers/npm_cache/tarball_extract.rs index 262618d905..c4c614b35f 100644 --- a/resolvers/npm_cache/tarball_extract.rs +++ b/resolvers/npm_cache/tarball_extract.rs @@ -219,8 +219,9 @@ fn get_atomic_dir_path(file_path: &Path) -> PathBuf { } fn gen_rand_path_component() -> String { - (0..4).fold(String::new(), |mut output, _| { - output.push_str(&format!("{:02x}", rand::random::())); + use std::fmt::Write; + (0..4).fold(String::with_capacity(8), |mut output, _| { + write!(&mut output, "{:02x}", rand::random::()).unwrap(); output }) } diff --git a/runtime/permissions/Cargo.toml b/runtime/permissions/Cargo.toml index 0140f0594e..5be45377a0 100644 --- a/runtime/permissions/Cargo.toml +++ b/runtime/permissions/Cargo.toml @@ -14,6 +14,7 @@ name = "deno_permissions" path = "lib.rs" [dependencies] +capacity_builder.workspace = true deno_core.workspace = true deno_path_util.workspace = true deno_terminal.workspace = true diff --git a/runtime/permissions/lib.rs b/runtime/permissions/lib.rs index a0b901d200..a1a217738d 100644 --- a/runtime/permissions/lib.rs +++ b/runtime/permissions/lib.rs @@ -1,5 +1,6 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +use capacity_builder::StringBuilder; use deno_core::parking_lot::Mutex; use deno_core::serde::de; use deno_core::serde::Deserialize; @@ -179,13 +180,18 @@ impl PermissionState { (Ok(()), false, false) } PermissionState::Prompt if prompt => { - let msg = format!( - "{} access{}", - name, - info() - .map(|info| { format!(" to {info}") }) - .unwrap_or_default(), - ); + let msg = { + let info = info(); + StringBuilder::build(|builder| { + builder.append(name); + builder.append(" access"); + if let Some(info) = &info { + builder.append(" to "); + builder.append(info); + } + }) + .unwrap() + }; match permission_prompt(&msg, name, api_name, true) { PromptResponse::Allow => { Self::log_perm_access(name, info); @@ -344,11 +350,11 @@ pub trait QueryDescriptor: Debug { fn overlaps_deny(&self, other: &Self::DenyDesc) -> bool; } -fn format_display_name(display_name: Cow) -> String { +fn format_display_name(display_name: Cow) -> Cow { if display_name.starts_with('<') && display_name.ends_with('>') { - display_name.into_owned() + display_name } else { - format!("\"{}\"", display_name) + Cow::Owned(format!("\"{}\"", display_name)) } } @@ -424,7 +430,7 @@ impl UnaryPermission { .check2( TQuery::flag_name(), api_name, - || desc.map(|d| format_display_name(d.display_name())), + || desc.map(|d| format_display_name(d.display_name()).into_owned()), self.prompt, ); if prompted { @@ -487,12 +493,17 @@ impl UnaryPermission { if !self.prompt { return PermissionState::Denied; } - let mut message = String::with_capacity(40); - message.push_str(&format!("{} access", TQuery::flag_name())); - if let Some(desc) = desc { - message - .push_str(&format!(" to {}", format_display_name(desc.display_name()))); - } + let maybe_formatted_display_name = + desc.map(|d| format_display_name(d.display_name())); + let message = StringBuilder::build(|builder| { + builder.append(TQuery::flag_name()); + builder.append(" access"); + if let Some(display_name) = &maybe_formatted_display_name { + builder.append(" to "); + builder.append(display_name) + } + }) + .unwrap(); match permission_prompt( &message, TQuery::flag_name(),