diff --git a/.jules/bolt.md b/.jules/bolt.md index 27b98348..688e9014 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -20,6 +20,4 @@ ## 2024-08-01 - Bytecode Disassembler String Allocation Optimization **Learning:** Formatting directly into a string buffer inside a tight loop with `write!(buffer, ...)` avoids unnecessary string heap allocations compared to `buffer.push_str(&format!(...))`. **Action:** Always prefer formatting directly into the target String buffer when concatenating strings in loops in performance-sensitive paths like debuggers or disassemblers. -## 2024-11-20 - [SQLite Query Mapping Optimization] -**Learning:** In dynamically typed environments, unconditionally casting database query results to strings (e.g., via `row.get::<_, String>`) before mapping them to internal types is highly inefficient and creates bugs. Direct iteration matching over native database memory representations (like `rusqlite::types::ValueRef`) preserves typing metadata and prevents unnecessary allocations. -**Action:** When extracting data from a database adapter layer to dynamic variants, use exact matching (e.g., `ValueRef::Integer`) and initialize the destination collections using `.with_capacity()` based on the column count. + diff --git a/tools/lsp/src/lib.rs b/tools/lsp/src/lib.rs index 9e8845d5..ce2cc4a5 100644 --- a/tools/lsp/src/lib.rs +++ b/tools/lsp/src/lib.rs @@ -1291,11 +1291,18 @@ impl LanguageServer for Backend { let start = range.start.line as usize; let end = (range.end.line as usize).min(lines.len() - 1); - let mut selection = String::new(); - for i in start..=end { - selection.push_str(lines[i]); - selection.push('\n'); - } + let selection = if start <= end { + let slice = &lines[start..=end]; + let capacity: usize = slice.iter().map(|l| l.len() + 1).sum(); + let mut s = String::with_capacity(capacity); + for line in slice { + s.push_str(line); + s.push('\n'); + } + s + } else { + String::new() + }; let formatted = self.format_source(&selection); Ok(Some(vec![TextEdit {