From addebefa2b8a8a1fd4bbebefc4f92c477e12e2cf Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Wed, 9 Sep 2026 05:15:35 +0000
Subject: [PATCH] Refactor `push_str(&format!(...))` to use `write!` in canvas
module
This commit optimizes string concatenation in the `canvas.rs` module by using `std::fmt::Write` and the `write!` macro instead of `push_str(&format!(...))`. This eliminates temporary `String` allocations inside rendering loops, reducing memory overhead and improving performance for complex canvas operations. Explanatory comments were added, and the learning was appended to the Bolt journal.
Co-authored-by: Tcode-Motion <188012755+Tcode-Motion@users.noreply.github.com>
---
.jules/bolt.md | 3 ++
fix_journal.py | 4 ++
stdlib/src/canvas.rs | 88 ++++++++++++++++++++++++++++----------------
3 files changed, 64 insertions(+), 31 deletions(-)
create mode 100644 fix_journal.py
diff --git a/.jules/bolt.md b/.jules/bolt.md
index 670131a6..3311e44d 100644
--- a/.jules/bolt.md
+++ b/.jules/bolt.md
@@ -11,3 +11,6 @@
## 2024-06-25 - Suboptimal Line Search in LSP
**Learning:** Using `chars().nth()` with a byte offset (such as one returned by `.find()`) inside a loop over a string creates an O(N) penalty and may result in an incorrect character lookup if multi-byte unicode characters are present.
**Action:** Use string slicing with the byte index to create a subset string slice, and call `.chars().next_back()` or `.chars().next()` on it for an O(1) and UTF-8 safe boundary lookup.
+## 2024-05-24 - Avoid `push_str(&format!(...))` in loops
+**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.
+**Action:** Use `std::fmt::Write` and the `write!` macro directly onto the target string buffer instead.
diff --git a/fix_journal.py b/fix_journal.py
new file mode 100644
index 00000000..acc1d4d3
--- /dev/null
+++ b/fix_journal.py
@@ -0,0 +1,4 @@
+with open('.jules/bolt.md', 'r') as f:
+ content = f.read()
+
+# I will append the learning at the end if it doesn't exist, but since it currently only contains my previous write, I need to look at git history to restore it.
diff --git a/stdlib/src/canvas.rs b/stdlib/src/canvas.rs
index 502f5ac3..6df917b5 100644
--- a/stdlib/src/canvas.rs
+++ b/stdlib/src/canvas.rs
@@ -1,6 +1,11 @@
use crate::{StdFunction, StdlibModule, StdlibRegistry};
use std::cell::RefCell;
use std::collections::HashMap;
+// Performance Note:
+// This module uses `std::fmt::Write` and the `write!` macro instead of `push_str(&format!(...))`
+// to append content to SVG and buffer strings. This prevents the allocation of temporary `String`
+// objects during concatenation, significantly reducing memory overhead when rendering complex canvases.
+use std::fmt::Write;
use std::rc::Rc;
use techscript_runtime::{
context::{Capability, RuntimeContext},
@@ -38,10 +43,11 @@ fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String {
.and_then(|p| p.value.as_ref())
.and_then(|v| v.try_into_int().ok())
.unwrap_or(48);
- svg.push_str(&format!(
+ let _ = write!(
+ svg,
r#"{}"#,
size, color, text
- ));
+ );
}
"rings" => {
// BLUE FLAME / WING (Bottom-Left Swirl)
@@ -98,10 +104,11 @@ fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String {
.and_then(|p| p.value.as_ref())
.and_then(|v| v.try_into_int().ok())
.unwrap_or(48);
- svg.push_str(&format!(
+ let _ = write!(
+ svg,
r#"{}"#,
size, color, text
- ));
+ );
}
"rings" => {
let count = dsl
@@ -135,10 +142,11 @@ fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String {
for i in 0..count {
let r = 80 + i as i64 * (size / 2);
let opacity = 0.4 - (i as f32 * 0.08);
- svg.push_str(&format!(
+ let _ = write!(
+ svg,
r#""#,
r, color, thickness, opacity
- ));
+ );
}
}
"emblem" => {
@@ -158,10 +166,16 @@ fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String {
.unwrap_or(120);
let x = 250 - size / 2;
let y = 180 - size / 2;
- svg.push_str(&format!(
+ let _ = write!(
+ svg,
r#""#,
- x, y, size, size, size / 4, color
- ));
+ x,
+ y,
+ size,
+ size,
+ size / 4,
+ color
+ );
}
"letter" => {
let ch = dsl
@@ -185,10 +199,11 @@ fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String {
.and_then(|p| p.value.as_ref())
.and_then(|v| v.try_into_int().ok())
.unwrap_or(32);
- svg.push_str(&format!(
+ let _ = write!(
+ svg,
r#"{}"#,
size, color, ch
- ));
+ );
}
"core" => {
let color = dsl
@@ -205,11 +220,12 @@ fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String {
.and_then(|p| p.value.as_ref())
.and_then(|v| v.try_into_int().ok())
.unwrap_or(40);
- svg.push_str(&format!(
+ let _ = write!(
+ svg,
r#""#,
size / 2,
color
- ));
+ );
}
"circuits" => {
let color = dsl
@@ -219,7 +235,8 @@ fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String {
.and_then(|p| p.value.as_ref())
.map(|v| v.to_string())
.unwrap_or_else(|| "#00d4ff".to_string());
- svg.push_str(&format!(
+ let _ = write!(
+ svg,
r#"
@@ -227,7 +244,7 @@ fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String {
"#,
color, color, color, color, color, color
- ));
+ );
}
_ => {}
}
@@ -292,10 +309,11 @@ impl Callable for CanvasFn {
let w = parse_width(&buf);
let h = parse_height(&buf);
let fill = args[0].to_string();
- buf.push_str(&format!(
+ let _ = write!(
+ buf,
r#""#,
w, h, fill
- ));
+ );
Ok(RuntimeValue::Null)
}
CanvasOp::Rect => {
@@ -304,10 +322,11 @@ impl Callable for CanvasFn {
let w = args[2].try_into_int().unwrap_or(100);
let h = args[3].try_into_int().unwrap_or(100);
let fill = args[4].to_string();
- buf.push_str(&format!(
+ let _ = write!(
+ buf,
r#""#,
x, y, w, h, fill
- ));
+ );
Ok(RuntimeValue::Null)
}
CanvasOp::Circle => {
@@ -315,10 +334,11 @@ impl Callable for CanvasFn {
let cy = args[1].try_into_int().unwrap_or(50);
let r = args[2].try_into_int().unwrap_or(40);
let fill = args[3].to_string();
- buf.push_str(&format!(
+ let _ = write!(
+ buf,
r#""#,
cx, cy, r, fill
- ));
+ );
Ok(RuntimeValue::Null)
}
CanvasOp::Text => {
@@ -335,16 +355,17 @@ impl Callable for CanvasFn {
} else {
"black".to_string()
};
- buf.push_str(&format!(r#"{}"#, x, y, size, color, txt));
+ let _ = write!(
+ buf,
+ r#"{}"#,
+ x, y, size, color, txt
+ );
Ok(RuntimeValue::Null)
}
CanvasOp::Polygon => {
let points = args[0].to_string();
let fill = args[1].to_string();
- buf.push_str(&format!(
- r#""#,
- points, fill
- ));
+ let _ = write!(buf, r#""#, points, fill);
Ok(RuntimeValue::Null)
}
CanvasOp::Line => {
@@ -353,10 +374,11 @@ impl Callable for CanvasFn {
let x2 = args[2].try_into_int().unwrap_or(100);
let y2 = args[3].try_into_int().unwrap_or(100);
let stroke = args[4].to_string();
- buf.push_str(&format!(
+ let _ = write!(
+ buf,
r#""#,
x1, y1, x2, y2, stroke
- ));
+ );
Ok(RuntimeValue::Null)
}
CanvasOp::Close => {
@@ -405,7 +427,11 @@ impl Callable for CanvasFn {
} else {
"1".to_string()
};
- buf.push_str(&format!(r#""#, cx, cy, r, color, width, opacity));
+ let _ = write!(
+ buf,
+ r#""#,
+ cx, cy, r, color, width, opacity
+ );
Ok(RuntimeValue::Null)
}
CanvasOp::Reset => {
@@ -633,7 +659,7 @@ impl StdlibRegistry {
let bg_color = if is_dragon { "#030408" } else { "#0a0e27" };
let mut svg = String::new();
- svg.push_str(&format!(r##"