[NOD-1387] Some small optimizations to block processing (#926)

* Preallocate when cloning utxoCollection/blockSet

* inline binary serialization to serializeUTXO

* Add a benchmark for serializeUTXO
This commit is contained in:
Elichai Turkel 2020-09-13 18:12:13 +03:00 committed by GitHub
parent 1e08bfca9c
commit e66de86a82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 71 additions and 29 deletions

View File

@ -375,30 +375,31 @@ func ReadVarInt(r io.Reader) (uint64, error) {
// on its value.
func WriteVarInt(w io.Writer, val uint64) error {
if val < 0xfd {
return binaryserializer.PutUint8(w, uint8(val))
_, err := w.Write([]byte{uint8(val)})
return errors.WithStack(err)
}
if val <= math.MaxUint16 {
err := binaryserializer.PutUint8(w, 0xfd)
if err != nil {
return err
}
return binaryserializer.PutUint16(w, littleEndian, uint16(val))
var buf [3]byte
buf[0] = 0xfd
littleEndian.PutUint16(buf[1:], uint16(val))
_, err := w.Write(buf[:])
return errors.WithStack(err)
}
if val <= math.MaxUint32 {
err := binaryserializer.PutUint8(w, 0xfe)
if err != nil {
return err
}
return binaryserializer.PutUint32(w, littleEndian, uint32(val))
var buf [5]byte
buf[0] = 0xfe
littleEndian.PutUint32(buf[1:], uint32(val))
_, err := w.Write(buf[:])
return errors.WithStack(err)
}
err := binaryserializer.PutUint8(w, 0xff)
if err != nil {
return err
}
return binaryserializer.PutUint64(w, littleEndian, val)
var buf [9]byte
buf[0] = 0xff
littleEndian.PutUint64(buf[1:], val)
_, err := w.Write(buf[:])
return errors.WithStack(err)
}
// VarIntSerializeSize returns the number of bytes it would take to serialize

View File

@ -36,7 +36,7 @@ func (bs blockSet) remove(node *blockNode) {
// clone clones thie block set
func (bs blockSet) clone() blockSet {
clone := newBlockSet()
clone := make(blockSet, len(bs))
for node := range bs {
clone.add(node)
}

View File

@ -55,7 +55,14 @@ func serializeOutpoint(w io.Writer, outpoint *appmessage.Outpoint) error {
return err
}
return binaryserializer.PutUint32(w, outpointIndexByteOrder, outpoint.Index)
var buf [4]byte
outpointIndexByteOrder.PutUint32(buf[:], outpoint.Index)
_, err = w.Write(buf[:])
if err != nil {
return errors.WithStack(err)
}
return nil
}
var outpointSerializeSize = daghash.TxIDSize + 4

View File

@ -2,6 +2,7 @@ package blockdag
import (
"bytes"
"encoding/binary"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/util/binaryserializer"
"github.com/kaspanet/kaspad/util/daghash"
@ -168,21 +169,18 @@ var p2pkhUTXOEntrySerializeSize = 8 + 8 + appmessage.VarIntSerializeSize(25) + 2
// serializeUTXOEntry encodes the entry to the given io.Writer and use compression if useCompression is true.
// The compression format is described in detail above.
func serializeUTXOEntry(w io.Writer, entry *UTXOEntry) error {
buf := [8 + 1 + 8]byte{}
// Encode the blueScore.
err := binaryserializer.PutUint64(w, byteOrder, entry.blockBlueScore)
if err != nil {
return err
}
binary.LittleEndian.PutUint64(buf[:8], entry.blockBlueScore)
// Encode the packedFlags.
err = binaryserializer.PutUint8(w, uint8(entry.packedFlags))
if err != nil {
return err
}
buf[8] = uint8(entry.packedFlags)
err = binaryserializer.PutUint64(w, byteOrder, entry.Amount())
binary.LittleEndian.PutUint64(buf[9:], entry.Amount())
_, err := w.Write(buf[:])
if err != nil {
return err
return errors.WithStack(err)
}
err = appmessage.WriteVarInt(w, uint64(len(entry.ScriptPubKey())))

View File

@ -0,0 +1,36 @@
package blockdag
import (
"bytes"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/util/daghash"
"testing"
)
func Benchmark_serializeUTXO(b *testing.B) {
entry := &UTXOEntry{
amount: 5000000000,
scriptPubKey: hexToBytes("76a914ad06dd6ddee55cbca9a9e3713bd7587509a3056488ac"), // p2pkh
blockBlueScore: 1432432,
packedFlags: 0,
}
outpoint := &appmessage.Outpoint{
TxID: daghash.TxID{
0x16, 0x5e, 0x38, 0xe8, 0xb3, 0x91, 0x45, 0x95,
0xd9, 0xc6, 0x41, 0xf3, 0xb8, 0xee, 0xc2, 0xf3,
0x46, 0x11, 0x89, 0x6b, 0x82, 0x1a, 0x68, 0x3b,
0x7a, 0x4e, 0xde, 0xfe, 0x2c, 0x00, 0x00, 0x00,
},
Index: 0xffffffff,
}
buf := bytes.NewBuffer(make([]byte, 8+1+8+9+len(entry.scriptPubKey)+len(outpoint.TxID)+4))
for i := 0; i < b.N; i++ {
buf.Reset()
err := serializeUTXO(buf, entry, outpoint)
if err != nil {
b.Fatal(err)
}
}
}

View File

@ -157,7 +157,7 @@ func (uc utxoCollection) containsWithBlueScore(outpoint appmessage.Outpoint, blu
// clone returns a clone of this collection
func (uc utxoCollection) clone() utxoCollection {
clone := utxoCollection{}
clone := make(utxoCollection, len(uc))
for outpoint, entry := range uc {
clone.add(outpoint, entry)
}