Skip to content

Commit 7231b4a

Browse files
committed
Add additional inline hints in serialization methods
This substantially improves deserialization performance when LLVM decides not to inline many short methods, eg when not building with LTO/codegen-units=1. Even with the default bench params of LTO/codegen-units=1, the serialization benchmarks on an Intel 2687W v3 take: test routing::network_graph::benches::read_network_graph ... bench: 1,955,616,225 ns/iter (+/- 4,135,777) test routing::network_graph::benches::write_network_graph ... bench: 165,905,275 ns/iter (+/- 118,798)
1 parent 583e6ac commit 7231b4a

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

lightning/src/util/ser.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,24 +60,29 @@ impl<W: Write> Writer for W {
6060

6161
pub(crate) struct WriterWriteAdaptor<'a, W: Writer + 'a>(pub &'a mut W);
6262
impl<'a, W: Writer + 'a> Write for WriterWriteAdaptor<'a, W> {
63+
#[inline]
6364
fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
6465
self.0.write_all(buf)
6566
}
67+
#[inline]
6668
fn write(&mut self, buf: &[u8]) -> Result<usize, ::std::io::Error> {
6769
self.0.write_all(buf)?;
6870
Ok(buf.len())
6971
}
72+
#[inline]
7073
fn flush(&mut self) -> Result<(), ::std::io::Error> {
7174
Ok(())
7275
}
7376
}
7477

7578
pub(crate) struct VecWriter(pub Vec<u8>);
7679
impl Writer for VecWriter {
80+
#[inline]
7781
fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
7882
self.0.extend_from_slice(buf);
7983
Ok(())
8084
}
85+
#[inline]
8186
fn size_hint(&mut self, size: usize) {
8287
self.0.reserve_exact(size);
8388
}
@@ -108,10 +113,12 @@ impl<R: Read> FixedLengthReader<R> {
108113
Self { read, bytes_read: 0, total_bytes }
109114
}
110115

116+
#[inline]
111117
pub fn bytes_remain(&mut self) -> bool {
112118
self.bytes_read != self.total_bytes
113119
}
114120

121+
#[inline]
115122
pub fn eat_remaining(&mut self) -> Result<(), DecodeError> {
116123
::std::io::copy(self, &mut ::std::io::sink()).unwrap();
117124
if self.bytes_read != self.total_bytes {
@@ -122,6 +129,7 @@ impl<R: Read> FixedLengthReader<R> {
122129
}
123130
}
124131
impl<R: Read> Read for FixedLengthReader<R> {
132+
#[inline]
125133
fn read(&mut self, dest: &mut [u8]) -> Result<usize, ::std::io::Error> {
126134
if self.total_bytes == self.bytes_read {
127135
Ok(0)
@@ -150,6 +158,7 @@ impl<R: Read> ReadTrackingReader<R> {
150158
}
151159
}
152160
impl<R: Read> Read for ReadTrackingReader<R> {
161+
#[inline]
153162
fn read(&mut self, dest: &mut [u8]) -> Result<usize, ::std::io::Error> {
154163
match self.read.read(dest) {
155164
Ok(0) => Ok(0),
@@ -234,6 +243,7 @@ pub trait MaybeReadable
234243

235244
pub(crate) struct OptionDeserWrapper<T: Readable>(pub Option<T>);
236245
impl<T: Readable> Readable for OptionDeserWrapper<T> {
246+
#[inline]
237247
fn read<R: Read>(reader: &mut R) -> Result<Self, DecodeError> {
238248
Ok(Self(Some(Readable::read(reader)?)))
239249
}
@@ -243,6 +253,7 @@ const MAX_ALLOC_SIZE: u64 = 64*1024;
243253

244254
pub(crate) struct VecWriteWrapper<'a, T: Writeable>(pub &'a Vec<T>);
245255
impl<'a, T: Writeable> Writeable for VecWriteWrapper<'a, T> {
256+
#[inline]
246257
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
247258
(self.0.len() as u64).write(writer)?;
248259
for ref v in self.0.iter() {
@@ -253,6 +264,7 @@ impl<'a, T: Writeable> Writeable for VecWriteWrapper<'a, T> {
253264
}
254265
pub(crate) struct VecReadWrapper<T: Readable>(pub Vec<T>);
255266
impl<T: Readable> Readable for VecReadWrapper<T> {
267+
#[inline]
256268
fn read<R: Read>(reader: &mut R) -> Result<Self, DecodeError> {
257269
let count: u64 = Readable::read(reader)?;
258270
let mut values = Vec::with_capacity(cmp::min(count, MAX_ALLOC_SIZE / (core::mem::size_of::<T>() as u64)) as usize);

0 commit comments

Comments
 (0)