From f97f6cf7ed516d0abec6c2f5d221b7793deaf5a4 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:18:21 +0000 Subject: [PATCH] perf(stdlib): eliminate string cloning in sys_write_file and sys_read_file Co-authored-by: Tcode-Motion <188012755+Tcode-Motion@users.noreply.github.com> --- .jules/bolt.md | 4 +++ runtime/runtime/src/value.rs | 7 +++++ stdlib/src/sys.rs | 59 +++++++++++++++++++++++++++++++++--- 3 files changed, 66 insertions(+), 4 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index 3faa4acb..b1a0edb5 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-10-28 - Standard Library File Operations String Allocation Optimization +**Learning:** Calling `try_into_string(&self)` on owned `RuntimeValue` arguments in standard library functions like `sys_write_file` and `sys_read_file` clones the string payload, causing redundant string allocations and memory copy overhead for file operations. +**Action:** Provide and use an `into_string(self)` method on `RuntimeValue` when owned arguments are available in standard library callback handlers to extract strings directly without allocation. diff --git a/runtime/runtime/src/value.rs b/runtime/runtime/src/value.rs index b9f91bdc..c5514704 100644 --- a/runtime/runtime/src/value.rs +++ b/runtime/runtime/src/value.rs @@ -212,6 +212,13 @@ impl RuntimeValue { } } + pub fn into_string(self) -> Result { + match self { + Self::Str(s) => Ok(s), + other => Ok(other.to_string()), + } + } + /// Verifies reference identity check (===). pub fn physical_eq(&self, other: &Self) -> bool { match (self, other) { diff --git a/stdlib/src/sys.rs b/stdlib/src/sys.rs index 00a45f14..7fcd2732 100644 --- a/stdlib/src/sys.rs +++ b/stdlib/src/sys.rs @@ -25,7 +25,20 @@ fn sys_read_file( args: Vec, ) -> Result { check_fs_capability(ctx)?; - let path = args[0].try_into_string()?; + let mut args_iter = args.into_iter(); + let path = args_iter + .next() + .ok_or_else(|| { + RuntimeError::new( + RuntimeErrorKind::ArityMismatch { + expected: 1, + found: 0, + }, + None, + None, + ) + })? + .into_string()?; let content = std::fs::read_to_string(path).map_err(|e| { RuntimeError::new( RuntimeErrorKind::InvalidOperation(format!("IO error: {}", e)), @@ -41,8 +54,33 @@ fn sys_write_file( args: Vec, ) -> Result { check_fs_capability(ctx)?; - let path = args[0].try_into_string()?; - let content = args[1].try_into_string()?; + let mut args_iter = args.into_iter(); + let path = args_iter + .next() + .ok_or_else(|| { + RuntimeError::new( + RuntimeErrorKind::ArityMismatch { + expected: 2, + found: 0, + }, + None, + None, + ) + })? + .into_string()?; + let content = args_iter + .next() + .ok_or_else(|| { + RuntimeError::new( + RuntimeErrorKind::ArityMismatch { + expected: 2, + found: 1, + }, + None, + None, + ) + })? + .into_string()?; std::fs::write(path, content).map_err(|e| { RuntimeError::new( RuntimeErrorKind::InvalidOperation(format!("IO error: {}", e)), @@ -58,7 +96,20 @@ fn sys_exists( args: Vec, ) -> Result { check_fs_capability(ctx)?; - let path = args[0].try_into_string()?; + let mut args_iter = args.into_iter(); + let path = args_iter + .next() + .ok_or_else(|| { + RuntimeError::new( + RuntimeErrorKind::ArityMismatch { + expected: 1, + found: 0, + }, + None, + None, + ) + })? + .into_string()?; Ok(RuntimeValue::Bool(std::path::Path::new(&path).exists())) }