Skip to content

Commit

Permalink
reduce async call depth
Browse files Browse the repository at this point in the history
Unfortunately Rust doesn't inline async functions, even for tail calls.
Each level of indirection adds to the state size and that can scale with
the amount of calls into the library.

Remove some avoidable uses of async to help memory usage somewhat until
Rust fixes these issues.

rust-lang/rust#69826
  • Loading branch information
tylerwhall committed Apr 12, 2022
1 parent e955dc7 commit 53f5c14
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 38 deletions.
40 changes: 20 additions & 20 deletions src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,44 +254,44 @@ impl<R: AsyncRead + Unpin> MsgPackFuture<R> {
}
}

async fn read_u8(&mut self) -> IoResult<u8> {
self.read_1().await
fn read_u8(&mut self) -> impl Future<Output = IoResult<u8>> + '_ {
self.read_1()
}

async fn read_u16(&mut self) -> IoResult<u16> {
Ok(BigEndian::read_u16(&self.read_2().await?))
fn read_u16(&mut self) -> impl Future<Output = IoResult<u16>> + '_ {
self.read_2().map_ok(|val| BigEndian::read_u16(&val))
}

async fn read_u32(&mut self) -> IoResult<u32> {
Ok(BigEndian::read_u32(&self.read_4().await?))
fn read_u32(&mut self) -> impl Future<Output = IoResult<u32>> + '_ {
self.read_4().map_ok(|val| BigEndian::read_u32(&val))
}

async fn read_u64(&mut self) -> IoResult<u64> {
Ok(BigEndian::read_u64(&self.read_8().await?))
fn read_u64(&mut self) -> impl Future<Output = IoResult<u64>> + '_ {
self.read_8().map_ok(|val| BigEndian::read_u64(&val))
}

async fn read_i8(&mut self) -> IoResult<i8> {
self.read_1().await.map(|x| x as i8)
fn read_i8(&mut self) -> impl Future<Output = IoResult<i8>> + '_ {
self.read_1().map_ok(|val| val as i8)
}

async fn read_i16(&mut self) -> IoResult<i16> {
Ok(BigEndian::read_i16(&self.read_2().await?))
fn read_i16(&mut self) -> impl Future<Output = IoResult<i16>> + '_ {
self.read_2().map_ok(|val| BigEndian::read_i16(&val))
}

async fn read_i32(&mut self) -> IoResult<i32> {
Ok(BigEndian::read_i32(&self.read_4().await?))
fn read_i32(&mut self) -> impl Future<Output = IoResult<i32>> + '_ {
self.read_4().map_ok(|val| BigEndian::read_i32(&val))
}

async fn read_i64(&mut self) -> IoResult<i64> {
Ok(BigEndian::read_i64(&self.read_8().await?))
fn read_i64(&mut self) -> impl Future<Output = IoResult<i64>> + '_ {
self.read_8().map_ok(|val| BigEndian::read_i64(&val))
}

async fn read_f32(&mut self) -> IoResult<f32> {
Ok(BigEndian::read_f32(&self.read_4().await?))
fn read_f32(&mut self) -> impl Future<Output = IoResult<f32>> + '_ {
self.read_4().map_ok(|val| BigEndian::read_f32(&val))
}

async fn read_f64(&mut self) -> IoResult<f64> {
Ok(BigEndian::read_f64(&self.read_8().await?))
fn read_f64(&mut self) -> impl Future<Output = IoResult<f64>> + '_ {
self.read_8().map_ok(|val| BigEndian::read_f64(&val))
}

pub async fn skip(self) -> IoResult<R>
Expand Down
36 changes: 18 additions & 18 deletions src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,54 +282,54 @@ impl<W: AsyncWrite + Unpin> MsgPackWriter<W> {
self.writer.write_all(&val).await
}

async fn write_u8(&mut self, val: u8) -> IoResult<()> {
fn write_u8(&mut self, val: u8) -> impl Future<Output = IoResult<()>> + '_ {
let buf = [val];
self.write_1(buf).await
self.write_1(buf)
}

async fn write_u16(&mut self, val: u16) -> IoResult<()> {
fn write_u16(&mut self, val: u16) -> impl Future<Output = IoResult<()>> + '_ {
let mut buf = [0u8; 2];
BigEndian::write_u16(&mut buf, val);
self.write_2(buf).await
self.write_2(buf)
}

async fn write_u32(&mut self, val: u32) -> IoResult<()> {
fn write_u32(&mut self, val: u32) -> impl Future<Output = IoResult<()>> + '_ {
let mut buf = [0u8; 4];
BigEndian::write_u32(&mut buf, val);
self.write_4(buf).await
self.write_4(buf)
}

async fn write_u64(&mut self, val: u64) -> IoResult<()> {
fn write_u64(&mut self, val: u64) -> impl Future<Output = IoResult<()>> + '_ {
let mut buf = [0u8; 8];
BigEndian::write_u64(&mut buf, val);
self.write_8(buf).await
self.write_8(buf)
}

async fn write_i8(&mut self, val: i8) -> IoResult<()> {
fn write_i8(&mut self, val: i8) -> impl Future<Output = IoResult<()>> + '_ {
let buf = [val as u8];
self.write_1(buf).await
self.write_1(buf)
}

async fn write_i16(&mut self, val: i16) -> IoResult<()> {
fn write_i16(&mut self, val: i16) -> impl Future<Output = IoResult<()>> + '_ {
let mut buf = [0u8; 2];
BigEndian::write_i16(&mut buf, val);
self.write_2(buf).await
self.write_2(buf)
}

async fn write_i32(&mut self, val: i32) -> IoResult<()> {
fn write_i32(&mut self, val: i32) -> impl Future<Output = IoResult<()>> + '_ {
let mut buf = [0u8; 4];
BigEndian::write_i32(&mut buf, val);
self.write_4(buf).await
self.write_4(buf)
}

async fn write_i64(&mut self, val: i64) -> IoResult<()> {
fn write_i64(&mut self, val: i64) -> impl Future<Output = IoResult<()>> + '_ {
let mut buf = [0u8; 8];
BigEndian::write_i64(&mut buf, val);
self.write_8(buf).await
self.write_8(buf)
}

async fn write_marker(&mut self, marker: Marker) -> IoResult<()> {
self.write_u8(marker.to_u8()).await
fn write_marker(&mut self, marker: Marker) -> impl Future<Output = IoResult<()>> + '_ {
self.write_u8(marker.to_u8())
}

pub async fn write_nil(mut self) -> IoResult<W> {
Expand Down

0 comments on commit 53f5c14

Please sign in to comment.