Skip to content

postgres/io: pre-allocate buffer capacity and use extend_from_slice i… - #4353

Closed
Aditya-9-6 wants to merge 2 commits into
transact-rs:mainfrom
Aditya-9-6:feature/postgres-buffer-reserve-capacity
Closed

postgres/io: pre-allocate buffer capacity and use extend_from_slice i…#4353
Aditya-9-6 wants to merge 2 commits into
transact-rs:mainfrom
Aditya-9-6:feature/postgres-buffer-reserve-capacity

Conversation

@Aditya-9-6

Copy link
Copy Markdown

Summary

This PR optimizes put_length_prefixed in sqlx-postgres/src/io/buf_mut.rs.

Rationale & Performance Benefit

Nearly all Postgres wire protocol messages sent to the database are length-prefixed. put_length_prefixed reserves the 4-byte length header at the beginning of each message.

Currently, it calls self.extend(&[0; 4]), which iterates over array elements and may trigger intermediate re-allocations if capacity is tight.

Optimizations made:

  • Pre-allocates space upfront with self.reserve(4).
  • Uses zero-copy self.extend_from_slice(&[0; 4]) slice copy instead of array iterator extension.
  • Streamlines database wire protocol encoding for high-throughput query pipelines.

…n put_length_prefixed

Signed-off-by: Aditya <adityadahale96@gmail.com>
Signed-off-by: Aditya <adityadahale96@gmail.com>
@abonander

Copy link
Copy Markdown
Collaborator

extend_from_slice just ends up in the same code path as extend: https://doc.rust-lang.org/stable/src/alloc/vec/mod.rs.html#3557

They both end up in the specialization for slice::Iter for bit-copyable elements (which the TrivialClone trait serves as a marker for): https://doc.rust-lang.org/stable/src/alloc/vec/spec_extend.rs.html#56

Which, first of all, calls reserve() anyway with the number of elements in the slice: https://doc.rust-lang.org/stable/src/alloc/vec/mod.rs.html#2932

And then does a direct ptr::copy_nonoverlapping().

This has existed since at least 1.80, much older than our current MSRV: https://doc.rust-lang.org/1.80.0/src/alloc/vec/mod.rs.html#2591

So this is not an optimization, it's just unnecessary diff churn. Just calling extend_from_slice might be slightly clearer in intent, but I doubt it makes an actual difference in performance. Since you don't provide any concrete performance figures, I assume you didn't benchmark it. This is why it's important to actually measure when doing optimizations, because your assumptions may turn out to be wrong.

@abonander abonander closed this Aug 17, 2026
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.

2 participants