Skip to content

Commit 0a484e4

Browse files
refactor(client): remove unnecessary allocations in SSE parsing (#13)
Replace Vec collect with peekable iterator in parse_sse_buffer to avoid heap allocation on the hot path. Use early return pattern to eliminate default String::new() allocation for the remaining buffer. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent afe6654 commit 0a484e4

File tree

1 file changed

+5
-8
lines changed

1 file changed

+5
-8
lines changed

crates/stringflow-core/src/client.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,18 @@ fn apply_auth_blocking(
4141
/// Parse SSE data lines from a buffer. Returns (events, remaining_buffer).
4242
fn parse_sse_buffer(buffer: &str, format: WireFormat) -> (Vec<StreamEvent>, String) {
4343
let mut events = Vec::new();
44-
let mut remaining = String::new();
4544

4645
// Split on double-newline (SSE event boundaries)
47-
let parts: Vec<&str> = buffer.split("\n\n").collect();
48-
let last_idx = parts.len().saturating_sub(1);
46+
let mut parts = buffer.split("\n\n").peekable();
4947

50-
for (i, chunk) in parts.iter().enumerate() {
48+
while let Some(chunk) = parts.next() {
5149
if chunk.is_empty() {
5250
continue;
5351
}
5452

5553
// Last chunk is incomplete if buffer didn't end with \n\n
56-
if i == last_idx && !buffer.ends_with("\n\n") {
57-
remaining = chunk.to_string();
58-
break;
54+
if parts.peek().is_none() && !buffer.ends_with("\n\n") {
55+
return (events, chunk.to_owned());
5956
}
6057

6158
for line in chunk.lines() {
@@ -71,7 +68,7 @@ fn parse_sse_buffer(buffer: &str, format: WireFormat) -> (Vec<StreamEvent>, Stri
7168
}
7269
}
7370

74-
(events, remaining)
71+
(events, String::new())
7572
}
7673

7774
// ============================================================================

0 commit comments

Comments
 (0)