Skip to content

Commit c072dea

Browse files
committed
Optimize BufReader somewhat for the only used case
`rust-bitcoin` doesn't ever actually *use* its `BufRead` requirement when deserializing objects, and forcing it is somewhat inefficient, so we optimize the only (actual) case here by passing reads straight through to the backing stream.
1 parent 05a598f commit c072dea

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

lightning/src/util/ser.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ impl<W: Write> Writer for W {
6666
}
6767
}
6868

69+
// Drop this entirely if rust-bitcoin releases a version bump with https://github.com/rust-bitcoin/rust-bitcoin/pull/3173
6970
/// Wrap buffering support for implementations of Read.
7071
/// A [`Read`]er which keeps an internal buffer to avoid hitting the underlying stream directly for
7172
/// every read, implementing [`BufRead`].
@@ -92,17 +93,21 @@ impl<'a, R: Read> BufReader<'a, R> {
9293
impl<'a, R: Read> Read for BufReader<'a, R> {
9394
#[inline]
9495
fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
95-
let input = self.fill_buf()?;
96-
let count = cmp::min(input.len(), output.len());
97-
output[..count].copy_from_slice(&input[..count]);
98-
self.consume(count);
99-
Ok(count)
96+
if output.is_empty() { return Ok(0); }
97+
let mut offset = 0;
98+
if !self.is_consumed {
99+
output[0] = self.buf[0];
100+
self.is_consumed = true;
101+
offset = 1;
102+
}
103+
self.inner.read(&mut output[offset..]).map(|len| len + offset)
100104
}
101105
}
102106

103107
impl<'a, R: Read> BufRead for BufReader<'a, R> {
104108
#[inline]
105109
fn fill_buf(&mut self) -> io::Result<&[u8]> {
110+
debug_assert!(false, "rust-bitcoin doesn't actually use this");
106111
if self.is_consumed {
107112
let count = self.inner.read(&mut self.buf[..])?;
108113
debug_assert!(count <= 1, "read gave us a garbage length");
@@ -120,6 +125,7 @@ impl<'a, R: Read> BufRead for BufReader<'a, R> {
120125

121126
#[inline]
122127
fn consume(&mut self, amount: usize) {
128+
debug_assert!(false, "rust-bitcoin doesn't actually use this");
123129
if amount >= 1 {
124130
debug_assert_eq!(amount, 1, "Can only consume one byte");
125131
debug_assert!(!self.is_consumed, "Cannot consume more than had been read");

0 commit comments

Comments
 (0)