Skip to content

perf: remove redundant copies and JS boundary crossings on hot paths#1022

Open
connyay wants to merge 1 commit into
cloudflare:mainfrom
connyay:cjh-efficiency
Open

perf: remove redundant copies and JS boundary crossings on hot paths#1022
connyay wants to merge 1 commit into
cloudflare:mainfrom
connyay:cjh-efficiency

Conversation

@connyay

@connyay connyay commented Jul 7, 2026

Copy link
Copy Markdown
Contributor
  • http/body.rs: Bytes::from(vec) instead of copy_from_slice, removing a second copy of every body chunk in the http-feature body bridge
  • d1: bind D1Type::Blob as an ArrayBuffer via Uint8Array (one memcpy) instead of serializing element-by-element into a JS number array
  • sql.rs: use js_sys::IteratorNext accessors instead of per-row Reflect::get with fresh key strings; drop the per-row Array.from copy in the raw cursor path
  • response.rs: Response::json() parses the buffered body in place instead of cloning it into a String via text()
  • response.rs: Response::cloned() duplicates fixed/empty bodies on the Rust side, reserving the JS Response.clone() tee for stream bodies

Adds a D1 blob round-trip integration test (previously uncovered).

- http/body.rs: Bytes::from(vec) instead of copy_from_slice, removing a
  second copy of every body chunk in the http-feature body bridge
- d1: bind D1Type::Blob as an ArrayBuffer via Uint8Array (one memcpy)
  instead of serializing element-by-element into a JS number array
- sql.rs: use js_sys::IteratorNext accessors instead of per-row
  Reflect::get with fresh key strings; drop the per-row Array.from copy
  in the raw cursor path
- response.rs: Response::json() parses the buffered body in place
  instead of cloning it into a String via text()
- response.rs: Response::cloned() duplicates fixed/empty bodies on the
  Rust side, reserving the JS Response.clone() tee for stream bodies

Adds a D1 blob round-trip integration test (previously uncovered).
Comment thread worker/src/d1/mod.rs
// D1's documented BLOB representation is an `ArrayBuffer`; copying
// through a `Uint8Array` crosses the JS boundary once instead of
// serializing element-by-element into a number array.
D1Type::Blob(a) => js_sys::Uint8Array::from(a).buffer().into(),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmph. this is a good change, but might break some consumers. Worth a break here IMO

Comment thread worker/src/http/body.rs
.poll_next_unpin(cx)
.map_ok(|buf| {
let bytes = Bytes::copy_from_slice(&js_sys::Uint8Array::from(buf).to_vec());
let bytes = Bytes::from(js_sys::Uint8Array::from(buf).to_vec());

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1 win in the PR. Maybe worth breaking to its own PR if the rest of it is spooky/controversial

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant