Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
27 changes: 25 additions & 2 deletions runtime/builtins/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
});
Expand Down
43 changes: 43 additions & 0 deletions runtime/builtins/tests/builtins_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}