Skip to content

Commit fa0e7b0

Browse files
⚡ Bolt: avoid temporary allocations in format string generation
Replaced `push_str(&format!(...))` with `let _ = write!(buffer, ...)` via `std::fmt::Write` in string generation loops in stdlib `web.rs`, `xml.rs` and `yaml.rs`. This prevents creating temporary strings that get immediately dropped and improves performance by writing directly to the target buffer. Co-authored-by: Tcode-Motion <188012755+Tcode-Motion@users.noreply.github.com>
1 parent c1b0660 commit fa0e7b0

4 files changed

Lines changed: 26 additions & 23 deletions

File tree

‎.jules/bolt.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@
1414
## 2024-05-24 - Avoid `push_str(&format!(...))` in loops
1515
**Learning:** Using `push_str(&format!(...))` inside loops creates unnecessary temporary String allocations because `format!` allocates a new `String` which is then appended and immediately dropped.
1616
**Action:** Use `std::fmt::Write` and the `write!` macro directly onto the target string buffer instead.
17+
## 2025-02-12 - String allocation optimization
18+
**Learning:** In heavily used loops, especially for rendering or stringifying tasks, `push_str(&format!(...))` allocates temporary strings unnecessarily. Replacing it with `write!` directly onto the mutable `String` buffer (using `std::fmt::Write`) skips the intermediate allocations and improves performance significantly.
19+
**Action:** Use `std::fmt::Write` and the `write!` macro instead of `push_str(&format!(...))` when generating strings in loops to prevent temporary allocations and improve performance.

‎stdlib/src/web.rs‎

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::{StdFunction, StdlibModule, StdlibRegistry};
22
use std::collections::HashMap;
3+
use std::fmt::Write;
34
use std::net::{IpAddr, SocketAddr, ToSocketAddrs};
45
use std::rc::Rc;
56
use std::sync::atomic::{AtomicBool, Ordering};
@@ -109,7 +110,7 @@ fn render_website(html: &mut String, dsl: &techscript_runtime::value::DslBlockVa
109110
match prop.name.as_str() {
110111
"title" => {
111112
if let Some(techscript_runtime::value::RuntimeValue::Str(t)) = &prop.value {
112-
html.push_str(&format!("<title>{}</title>", t));
113+
let _ = write!(html, "<title>{}</title>", t);
113114
}
114115
}
115116
_ => {}
@@ -148,12 +149,12 @@ fn render_website(html: &mut String, dsl: &techscript_runtime::value::DslBlockVa
148149
fn render_page(html: &mut String, dsl: &techscript_runtime::value::DslBlockValue) {
149150
html.push_str("<div class=\"page\">");
150151
if let Some(techscript_runtime::value::RuntimeValue::Str(t)) = dsl.args.first() {
151-
html.push_str(&format!("<h1>{}</h1>", t));
152+
let _ = write!(html, "<h1>{}</h1>", t);
152153
}
153154
for prop in &dsl.properties {
154155
if prop.name == "title" {
155156
if let Some(techscript_runtime::value::RuntimeValue::Str(t)) = &prop.value {
156-
html.push_str(&format!("<h2>{}</h2>", t));
157+
let _ = write!(html, "<h2>{}</h2>", t);
157158
}
158159
}
159160
}
@@ -167,12 +168,12 @@ fn render_hero(html: &mut String, dsl: &techscript_runtime::value::DslBlockValue
167168
match prop.name.as_str() {
168169
"title" => {
169170
if let Some(techscript_runtime::value::RuntimeValue::Str(t)) = &prop.value {
170-
html.push_str(&format!("<h1>{}</h1>", t));
171+
let _ = write!(html, "<h1>{}</h1>", t);
171172
}
172173
}
173174
"subtitle" => {
174175
if let Some(techscript_runtime::value::RuntimeValue::Str(t)) = &prop.value {
175-
html.push_str(&format!("<p class=\"subtitle\">{}</p>", t));
176+
let _ = write!(html, "<p class=\"subtitle\">{}</p>", t);
176177
}
177178
}
178179
_ => {}
@@ -188,12 +189,12 @@ fn render_section(html: &mut String, dsl: &techscript_runtime::value::DslBlockVa
188189
match prop.name.as_str() {
189190
"title" => {
190191
if let Some(techscript_runtime::value::RuntimeValue::Str(t)) = &prop.value {
191-
html.push_str(&format!("<h2>{}</h2>", t));
192+
let _ = write!(html, "<h2>{}</h2>", t);
192193
}
193194
}
194195
"id" => {
195196
if let Some(techscript_runtime::value::RuntimeValue::Str(t)) = &prop.value {
196-
html.push_str(&format!("<!-- id: {} -->", t));
197+
let _ = write!(html, "<!-- id: {} -->", t);
197198
}
198199
}
199200
_ => {}
@@ -211,17 +212,17 @@ fn render_card(html: &mut String, dsl: &techscript_runtime::value::DslBlockValue
211212
match prop.name.as_str() {
212213
"title" => {
213214
if let Some(techscript_runtime::value::RuntimeValue::Str(t)) = &prop.value {
214-
html.push_str(&format!("<h3>{}</h3>", t));
215+
let _ = write!(html, "<h3>{}</h3>", t);
215216
}
216217
}
217218
"text" => {
218219
if let Some(techscript_runtime::value::RuntimeValue::Str(t)) = &prop.value {
219-
html.push_str(&format!("<p>{}</p>", t));
220+
let _ = write!(html, "<p>{}</p>", t);
220221
}
221222
}
222223
"image" => {
223224
if let Some(techscript_runtime::value::RuntimeValue::Str(t)) = &prop.value {
224-
html.push_str(&format!("<img src=\"{}\" alt=\"card image\">", t));
225+
let _ = write!(html, "<img src=\"{}\" alt=\"card image\">", t);
225226
}
226227
}
227228
_ => {}
@@ -259,7 +260,7 @@ fn dsl_to_html(val: &RuntimeValue) -> String {
259260
.and_then(|p| p.value.as_ref())
260261
.map(|v| v.to_string())
261262
.unwrap_or_else(|| "Button".to_string());
262-
html.push_str(&format!("<button>{}</button>", label));
263+
let _ = write!(html, "<button>{}</button>", label);
263264
}
264265
"link" => {
265266
let label = dsl
@@ -276,9 +277,9 @@ fn dsl_to_html(val: &RuntimeValue) -> String {
276277
.and_then(|p| p.value.as_ref())
277278
.map(|v| v.to_string());
278279
if let Some(u) = url {
279-
html.push_str(&format!("<a href=\"{}\">{}</a>", u, label));
280+
let _ = write!(html, "<a href=\"{}\">{}</a>", u, label);
280281
} else {
281-
html.push_str(&format!("<a href=\"#\">{}</a>", label));
282+
let _ = write!(html, "<a href=\"#\">{}</a>", label);
282283
}
283284
}
284285
"nav" => {
@@ -291,7 +292,7 @@ fn dsl_to_html(val: &RuntimeValue) -> String {
291292
for prop in &dsl.properties {
292293
if prop.name == "title" {
293294
if let Some(RuntimeValue::Str(t)) = &prop.value {
294-
html.push_str(&format!("<h1>{}</h1>", t));
295+
let _ = write!(html, "<h1>{}</h1>", t);
295296
}
296297
}
297298
}
@@ -303,7 +304,7 @@ fn dsl_to_html(val: &RuntimeValue) -> String {
303304
for prop in &dsl.properties {
304305
if prop.name == "text" {
305306
if let Some(RuntimeValue::Str(t)) = &prop.value {
306-
html.push_str(&format!("<p>{}</p>", t));
307+
let _ = write!(html, "<p>{}</p>", t);
307308
}
308309
}
309310
}
@@ -318,7 +319,7 @@ fn dsl_to_html(val: &RuntimeValue) -> String {
318319
.and_then(|p| p.value.as_ref())
319320
.map(|v| v.to_string());
320321
if let Some(p) = placeholder {
321-
html.push_str(&format!("<input placeholder=\"{}\">", p));
322+
let _ = write!(html, "<input placeholder=\"{}\">", p);
322323
} else {
323324
html.push_str("<input>");
324325
}
@@ -346,13 +347,10 @@ fn dsl_to_html(val: &RuntimeValue) -> String {
346347
.and_then(|p| p.value.as_ref())
347348
.map(|v| v.to_string())
348349
.unwrap_or_else(|| "Get Started".to_string());
349-
html.push_str(&format!(
350-
"<a class=\"start-button\" href=\"#\">{}</a>",
351-
label
352-
));
350+
let _ = write!(html, "<a class=\"start-button\" href=\"#\">{}</a>", label);
353351
}
354352
_ => {
355-
html.push_str(&format!("<!-- unknown DSL block: {} -->", dsl.kind));
353+
let _ = write!(html, "<!-- unknown DSL block: {} -->", dsl.kind);
356354
}
357355
}
358356
html

‎stdlib/src/xml.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::{StdFunction, StdlibModule, StdlibRegistry};
22
use indexmap::IndexMap;
33
use std::cell::RefCell;
44
use std::collections::HashMap;
5+
use std::fmt::Write;
56
use std::rc::Rc;
67
use techscript_runtime::{error::RuntimeError, value::RuntimeValue};
78

@@ -44,7 +45,7 @@ impl StdlibRegistry {
4445
if let RuntimeValue::Map { entries, .. } = &args[0] {
4546
for (k, v) in entries.borrow().iter() {
4647
let val_str = v.try_into_string().unwrap_or_default();
47-
result.push_str(&format!("<{}>{}</{}>", k, val_str, k));
48+
let _ = write!(result, "<{}>{}</{}>", k, val_str, k);
4849
}
4950
}
5051
Ok(RuntimeValue::Str(result))

‎stdlib/src/yaml.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::{StdFunction, StdlibModule, StdlibRegistry};
22
use indexmap::IndexMap;
33
use std::cell::RefCell;
44
use std::collections::HashMap;
5+
use std::fmt::Write;
56
use std::rc::Rc;
67
use techscript_runtime::{error::RuntimeError, value::RuntimeValue};
78

@@ -47,7 +48,7 @@ impl StdlibRegistry {
4748
if let RuntimeValue::Map { entries, .. } = &args[0] {
4849
for (k, v) in entries.borrow().iter() {
4950
let val_str = v.try_into_string().unwrap_or_default();
50-
result.push_str(&format!("{}: {}\n", k, val_str));
51+
let _ = write!(result, "{}: {}\n", k, val_str);
5152
}
5253
}
5354
Ok(RuntimeValue::Str(result))

0 commit comments

Comments
 (0)