From d56aee254604bba5afee45c72d55fad095a5bb09 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 19 Sep 2026 05:26:19 +0000 Subject: [PATCH] Optimize recursive string allocations in canvas SVG rendering\n\nReplaced recursive `String` returns in Canvas DSL rendering with a mutable `&mut String` buffer parameter. Deeply nested structures generated a new `String` at each level, causing severe memory allocation overhead during concatenation. Reusing a single buffer avoids these intermediate allocations. Co-authored-by: Tcode-Motion <188012755+Tcode-Motion@users.noreply.github.com> --- stdlib/src/canvas.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/stdlib/src/canvas.rs b/stdlib/src/canvas.rs index 6df917b5..3c4b3302 100644 --- a/stdlib/src/canvas.rs +++ b/stdlib/src/canvas.rs @@ -15,10 +15,9 @@ use techscript_runtime::{ }; /// Convert a DslBlockValue to SVG string. -fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String { +fn render_dsl_to_svg(svg: &mut String, val: &RuntimeValue, is_dragon: bool) { match val { RuntimeValue::DslBlock(dsl) => { - let mut svg = String::new(); if is_dragon { match dsl.kind.as_str() { "logo" => { @@ -249,12 +248,17 @@ fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String { _ => {} } } - svg } - _ => String::new(), + _ => {} } } +fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String { + let mut svg = String::new(); + render_dsl_to_svg(&mut svg, val, is_dragon); + svg +} + struct CanvasFn { name: String, min_arity: usize, @@ -684,7 +688,7 @@ impl StdlibRegistry { "##, bg_color); for block in &blocks { - svg.push_str(&dsl_to_svg(block, is_dragon)); + render_dsl_to_svg(&mut svg, block, is_dragon); } svg.push_str(""); Ok(RuntimeValue::Str(svg))