peer_protocol.Decoder.Decode: Avoid allocating another intermediate reader
On my system, BenchmarkConnectionMainReadLoop goes from 596 to 1311 MB/s.
This commit is contained in:
parent
23efae91e2
commit
47ef753795
|
@ -128,6 +128,20 @@ type Decoder struct {
|
||||||
MaxLength Integer // TODO: Should this include the length header or not?
|
MaxLength Integer // TODO: Should this include the length header or not?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readByte(r io.Reader) (b byte, err error) {
|
||||||
|
var arr [1]byte
|
||||||
|
n, err := r.Read(arr[:])
|
||||||
|
b = arr[0]
|
||||||
|
if n == 1 {
|
||||||
|
err = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// io.EOF is returned if the source terminates cleanly on a message boundary.
|
// io.EOF is returned if the source terminates cleanly on a message boundary.
|
||||||
func (d *Decoder) Decode(msg *Message) (err error) {
|
func (d *Decoder) Decode(msg *Message) (err error) {
|
||||||
var length Integer
|
var length Integer
|
||||||
|
@ -146,29 +160,18 @@ func (d *Decoder) Decode(msg *Message) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
msg.Keepalive = false
|
msg.Keepalive = false
|
||||||
b := make([]byte, length)
|
r := &io.LimitedReader{d.R, int64(length)}
|
||||||
_, err = io.ReadFull(d.R, b)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
err = io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
if err != io.ErrUnexpectedEOF {
|
|
||||||
err = fmt.Errorf("error reading message: %s", err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
r := bytes.NewReader(b)
|
|
||||||
// Check that all of r was utilized.
|
// Check that all of r was utilized.
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if r.Len() != 0 {
|
if r.N != 0 {
|
||||||
err = fmt.Errorf("%d bytes unused in message type %d", r.Len(), msg.Type)
|
err = fmt.Errorf("%d bytes unused in message type %d", r.N, msg.Type)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
msg.Keepalive = false
|
msg.Keepalive = false
|
||||||
c, err := r.ReadByte()
|
c, err := readByte(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -210,7 +213,7 @@ func (d *Decoder) Decode(msg *Message) (err error) {
|
||||||
}
|
}
|
||||||
msg.Piece = b
|
msg.Piece = b
|
||||||
case Extended:
|
case Extended:
|
||||||
msg.ExtendedID, err = r.ReadByte()
|
msg.ExtendedID, err = readByte(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue