state: create buffer/io writer once per TokenTransferLog

name                       old time/op    new time/op    delta
TokenTransferLog_Append-8   93.0µs ±170%   46.8µs ±152%     ~     (p=0.053 n=10+9)

name                       old alloc/op   new alloc/op   delta
TokenTransferLog_Append-8    53.8kB ± 4%    38.6kB ±39%  -28.26%  (p=0.004 n=8+10)

name                       old allocs/op  new allocs/op  delta
TokenTransferLog_Append-8       384 ± 0%       128 ± 0%  -66.67%  (p=0.000 n=10+10)
This commit is contained in:
Roman Khimov 2022-06-03 23:49:51 +03:00
parent 1e5825c4af
commit 799394192b
2 changed files with 22 additions and 8 deletions

View file

@ -1454,7 +1454,7 @@ func appendTokenTransfer(cache *dao.Simple, transCache map[util.Uint160]transfer
*nextBatch++ *nextBatch++
*currTimestamp = bTimestamp *currTimestamp = bTimestamp
// Put makes a copy of it anyway. // Put makes a copy of it anyway.
log.Raw = log.Raw[:0] log.Reset()
} }
transCache[addr] = transferData transCache[addr] = transferData
return nil return nil

View file

@ -16,6 +16,8 @@ const TokenTransferBatchSize = 128
// TokenTransferLog is a serialized log of token transfers. // TokenTransferLog is a serialized log of token transfers.
type TokenTransferLog struct { type TokenTransferLog struct {
Raw []byte Raw []byte
buf *bytes.Buffer
iow *io.BinWriter
} }
// NEP17Transfer represents a single NEP-17 Transfer event. // NEP17Transfer represents a single NEP-17 Transfer event.
@ -111,18 +113,30 @@ func (lg *TokenTransferLog) Append(tr io.Serializable) error {
lg.Raw = append(lg.Raw, 0) lg.Raw = append(lg.Raw, 0)
} }
b := bytes.NewBuffer(lg.Raw) if lg.buf == nil {
w := io.NewBinWriterFromIO(b) lg.buf = bytes.NewBuffer(lg.Raw)
tr.EncodeBinary(w)
if w.Err != nil {
return w.Err
} }
lg.Raw = b.Bytes() if lg.iow == nil {
lg.iow = io.NewBinWriterFromIO(lg.buf)
}
tr.EncodeBinary(lg.iow)
if lg.iow.Err != nil {
return lg.iow.Err
}
lg.Raw = lg.buf.Bytes()
lg.Raw[0]++ lg.Raw[0]++
return nil return nil
} }
// Reset resets the state of the log, clearing all entries, but keeping existing
// buffer for future writes.
func (lg *TokenTransferLog) Reset() {
lg.Raw = lg.Raw[:0]
lg.buf = nil
lg.iow = nil
}
// ForEachNEP11 iterates over a transfer log returning on the first error. // ForEachNEP11 iterates over a transfer log returning on the first error.
func (lg *TokenTransferLog) ForEachNEP11(f func(*NEP11Transfer) (bool, error)) (bool, error) { func (lg *TokenTransferLog) ForEachNEP11(f func(*NEP11Transfer) (bool, error)) (bool, error) {
if lg == nil || len(lg.Raw) == 0 { if lg == nil || len(lg.Raw) == 0 {