From 7137082bccf4a082938ca2e968fac84a393cb594 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 27 Oct 2026 18:22:23 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9A=A1=20Optimize=20String=20allocations?= =?UTF-8?q?=20and=20formatting=20in=20fstring=5Fconcat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tcode-Motion <188012755+Tcode-Motion@users.noreply.github.com> --- .jules/bolt.md | 4 +++ runtime/builtins/src/lib.rs | 27 +++++++++++++-- runtime/builtins/tests/builtins_tests.rs | 43 ++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index 3faa4acb..9ad2878d 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -70,3 +70,7 @@ ## 2024-05-24 - Web Property Extraction Optimization **Learning:** Extracting properties from the `RuntimeValue` DSL property lists in `stdlib/src/web/renderer.rs` and `stdlib/src/web/db.rs` was inefficient because the code called `.iter().find()` to resolve `text`, `id`, and `name` attributes, which creates unnecessary iterator overhead and closure allocation. **Action:** Replace `.iter().find()` calls with a single-pass `for p in &dsl.properties` loop and `if` statements on the property names, stopping early when found, which significantly reduces execution overhead. + +## 2026-09-29 - Pre-allocated String Buffer in Native fstring_concat +**Learning:** Creating empty String buffers with `String::new()` in string concatenation loops (`fstring_concat`) causes repeated heap re-allocations as formatted components are appended. Pre-calculating total expected capacity using `String::with_capacity(capacity)` and utilizing direct `push_str` calls for `Value::Str` and `Value::Bool` bypasses both buffer reallocations and `write!` macro formatting dispatch overhead. +**Action:** Always sum argument lengths upfront to call `String::with_capacity` and prefer `push_str` over `write!` macros when concatenating string values in runtime built-ins. diff --git a/runtime/builtins/src/lib.rs b/runtime/builtins/src/lib.rs index fb638947..119002fb 100644 --- a/runtime/builtins/src/lib.rs +++ b/runtime/builtins/src/lib.rs @@ -85,9 +85,32 @@ impl BuiltinRegistry { Ok(Value::Null) }); self.register("fstring_concat", |args| { - let mut res = String::new(); + let capacity: usize = args + .iter() + .map(|arg| match arg { + Value::Str(s) => s.len(), + Value::Int(_) => 12, + Value::Float(_) => 16, + Value::Bool(b) => { + if *b { + 4 + } else { + 5 + } + } + _ => 16, + }) + .sum(); + let mut res = String::with_capacity(capacity); for arg in args { - let _ = write!(res, "{}", arg); + match arg { + Value::Str(s) => res.push_str(s), + Value::Bool(true) => res.push_str("true"), + Value::Bool(false) => res.push_str("false"), + _ => { + let _ = write!(res, "{}", arg); + } + } } Ok(Value::Str(res)) }); diff --git a/runtime/builtins/tests/builtins_tests.rs b/runtime/builtins/tests/builtins_tests.rs index 27c304be..d3e75d9f 100644 --- a/runtime/builtins/tests/builtins_tests.rs +++ b/runtime/builtins/tests/builtins_tests.rs @@ -11,3 +11,46 @@ fn test_builtins_len() { let val = registry.call("len", &args).expect("len should run"); assert_eq!(val, Value::Int(5)); } + +#[test] +fn test_fstring_concat() { + let registry = BuiltinRegistry::new(); + assert!(registry.has_function("fstring_concat")); + + let args = vec![ + Value::Str("Hello, ".to_string()), + Value::Str("World".to_string()), + Value::Str("! Number: ".to_string()), + Value::Int(42), + Value::Str(" Bool: ".to_string()), + Value::Bool(true), + ]; + + let val = registry + .call("fstring_concat", &args) + .expect("fstring_concat should run"); + assert_eq!( + val, + Value::Str("Hello, World! Number: 42 Bool: true".to_string()) + ); +} + +#[test] +fn benchmark_fstring_concat() { + let registry = BuiltinRegistry::new(); + let args = vec![ + Value::Str("Hello, ".to_string()), + Value::Str("World".to_string()), + Value::Str("! Number: ".to_string()), + Value::Int(42), + Value::Str(" Bool: ".to_string()), + Value::Bool(true), + ]; + + let start = std::time::Instant::now(); + for _ in 0..100_000 { + let _ = registry.call("fstring_concat", &args); + } + let elapsed = start.elapsed(); + println!("100,000 fstring_concat runs took: {:?}", elapsed); +} From 26644eca70cb52b803bc11d3eb0aea8388de529c Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 27 Oct 2026 19:36:36 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9A=A1=20Optimize=20String=20allocations?= =?UTF-8?q?=20and=20formatting=20in=20fstring=5Fconcat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tcode-Motion <188012755+Tcode-Motion@users.noreply.github.com>