diff --git a/.changelog/unreleased/improvements/3019-reduce-allocations-in-packet-reads.md b/.changelog/unreleased/improvements/3019-reduce-allocations-in-packet-reads.md new file mode 100644 index 00000000000..604002636a9 --- /dev/null +++ b/.changelog/unreleased/improvements/3019-reduce-allocations-in-packet-reads.md @@ -0,0 +1,3 @@ +- [`protoio`] Remove one allocation and new object call from `ReadMsg`, + leading to a 4% p2p message reading performance gain. + ([\#3018](https://github.com/cometbft/cometbft/issues/3018) diff --git a/.golangci.yml b/.golangci.yml index d7db8f833c0..c9a29c49046 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -43,6 +43,8 @@ linters-settings: suggest-new: true misspell: locale: US + ignore-words: + - Cancelled depguard: rules: main: diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d893481972..6322c68b7a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,15 @@ ## Unreleased +* [#73](https://github.com/osmosis-labs/cometbft/pull/73) perf(consensus/blockexec): Add simplistic block validation cache +* [#74](https://github.com/osmosis-labs/cometbft/pull/74) perf(consensus): Minor speedup to mark late vote metrics +* [#75](https://github.com/osmosis-labs/cometbft/pull/75) perf(p2p): 4% speedup to readMsg by removing one allocation + ## v0.37.4-v25-osmo-3 * [#61](https://github.com/osmosis-labs/cometbft/pull/61) refactor(p2p/connection): Slight refactor to sendManyPackets that helps highlight performance improvements (backport #2953) (#2978) * [#62](https://github.com/osmosis-labs/cometbft/pull/62) perf(consensus/blockstore): Remove validate basic call from LoadBlock * [#71](https://github.com/osmosis-labs/cometbft/pull/71) perf(consensus): Make mempool update async from Commit -* [#73](https://github.com/osmosis-labs/cometbft/pull/73) perf(consensus/blockexec): Add simplistic block validation cache -* [#74](https://github.com/osmosis-labs/cometbft/pull/74) perf(consensus): Minor speedup to mark late vote metrics * [#59](https://github.com/osmosis-labs/cometbft/pull/59) `[blockstore]` Remove a redundant `Header.ValidateBasic` call in `LoadBlockMeta`, 75% reducing this time. ([\#2964](https://github.com/cometbft/cometbft/pull/2964)) * [#59](https://github.com/osmosis-labs/cometbft/pull/59) `[p2p/conn]` Speedup connection.WritePacketMsgTo, by reusing internal buffers rather than re-allocating. ([\#2986](https://github.com/cometbft/cometbft/pull/2986)) diff --git a/libs/protoio/io.go b/libs/protoio/io.go index 6244afd97b6..d024f6a04f8 100644 --- a/libs/protoio/io.go +++ b/libs/protoio/io.go @@ -97,3 +97,7 @@ func (r *byteReader) ReadByte() (byte, error) { } return r.buf[0], nil } + +func (r *byteReader) resetBytesRead() { + r.bytesRead = 0 +} diff --git a/libs/protoio/reader.go b/libs/protoio/reader.go index 95b8d345585..054a114df8b 100644 --- a/libs/protoio/reader.go +++ b/libs/protoio/reader.go @@ -49,24 +49,25 @@ func NewDelimitedReader(r io.Reader, maxSize int) ReadCloser { if c, ok := r.(io.Closer); ok { closer = c } - return &varintReader{r, nil, maxSize, closer} + return &varintReader{r, newByteReader(r), nil, maxSize, closer} } type varintReader struct { - r io.Reader - buf []byte - maxSize int - closer io.Closer -} - -func (r *varintReader) ReadMsg(msg proto.Message) (int, error) { + r io.Reader // ReadUvarint needs an io.ByteReader, and we also need to keep track of the // number of bytes read, so we use our own byteReader. This can't be // buffered, so the caller should pass a buffered io.Reader to avoid poor // performance. - byteReader := newByteReader(r.r) - l, err := binary.ReadUvarint(byteReader) - n := byteReader.bytesRead + byteReader *byteReader + buf []byte + maxSize int + closer io.Closer +} + +func (r *varintReader) ReadMsg(msg proto.Message) (int, error) { + r.byteReader.resetBytesRead() + l, err := binary.ReadUvarint(r.byteReader) + n := r.byteReader.bytesRead if err != nil { return n, err } diff --git a/libs/pubsub/subscription.go b/libs/pubsub/subscription.go index 3c9046792f5..435a30e3de5 100644 --- a/libs/pubsub/subscription.go +++ b/libs/pubsub/subscription.go @@ -45,8 +45,6 @@ func (s *Subscription) Out() <-chan Message { // Cancelled returns a channel that's closed when the subscription is // terminated and supposed to be used in a select statement. -// -//nolint:misspell func (s *Subscription) Cancelled() <-chan struct{} { return s.canceled } diff --git a/types/event_bus.go b/types/event_bus.go index b22df3b9dad..580254561c3 100644 --- a/types/event_bus.go +++ b/types/event_bus.go @@ -23,7 +23,7 @@ type EventBusSubscriber interface { type Subscription interface { Out() <-chan cmtpubsub.Message - Cancelled() <-chan struct{} //nolint: misspell + Cancelled() <-chan struct{} Err() error }