Skip to content

Commit ffd7245

Browse files
committed
Use BytesMut for messages
Benchmarks indicate that malloc accounts for a significant amount of the runtime of queries. The message buffer accounts for ~half of that (the other being channels), and this change should eliminate it.
1 parent e99d65e commit ffd7245

30 files changed

+390
-414
lines changed

postgres-derive/src/tosql.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub fn expand_derive_tosql(input: DeriveInput) -> Result<TokenStream, Error> {
5959
impl postgres_types::ToSql for #ident {
6060
fn to_sql(&self,
6161
_type: &postgres_types::Type,
62-
buf: &mut std::vec::Vec<u8>)
62+
buf: &mut postgres_types::private::BytesMut)
6363
-> std::result::Result<postgres_types::IsNull,
6464
std::boxed::Box<std::error::Error +
6565
std::marker::Sync +

postgres-protocol/src/lib.rs

+28-4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#![warn(missing_docs, rust_2018_idioms, clippy::all)]
1414

1515
use byteorder::{BigEndian, ByteOrder};
16+
use bytes::{BufMut, BytesMut};
1617
use std::io;
1718

1819
pub mod authentication;
@@ -30,14 +31,37 @@ pub enum IsNull {
3031
No,
3132
}
3233

33-
#[inline]
34-
fn write_nullable<F, E>(serializer: F, buf: &mut Vec<u8>) -> Result<(), E>
34+
// https://github.com/tokio-rs/bytes/issues/170
35+
struct B<'a>(&'a mut BytesMut);
36+
37+
impl<'a> BufMut for B<'a> {
38+
#[inline]
39+
fn remaining_mut(&self) -> usize {
40+
usize::max_value() - self.0.len()
41+
}
42+
43+
#[inline]
44+
unsafe fn advance_mut(&mut self, cnt: usize) {
45+
self.0.advance_mut(cnt);
46+
}
47+
48+
#[inline]
49+
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
50+
if !self.0.has_remaining_mut() {
51+
self.0.reserve(64);
52+
}
53+
54+
self.0.bytes_mut()
55+
}
56+
}
57+
58+
fn write_nullable<F, E>(serializer: F, buf: &mut BytesMut) -> Result<(), E>
3559
where
36-
F: FnOnce(&mut Vec<u8>) -> Result<IsNull, E>,
60+
F: FnOnce(&mut BytesMut) -> Result<IsNull, E>,
3761
E: From<io::Error>,
3862
{
3963
let base = buf.len();
40-
buf.extend_from_slice(&[0; 4]);
64+
B(buf).put_i32_be(0);
4165
let size = match serializer(buf)? {
4266
IsNull::No => i32::from_usize(buf.len() - base - 4)?,
4367
IsNull::Yes => -1,

0 commit comments

Comments
 (0)