diff options
author | Mission Liao <mission.liao@dexon.org> | 2018-08-28 13:13:21 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-28 13:13:21 +0800 |
commit | 7e9d2db5576d697b578669c935b2e7bbf9422ec7 (patch) | |
tree | e4fb9f4b95b23934a142a88ee05fbd49dff50b3c /core/types | |
parent | 9c8f9a447bfd768a7b29db904bd604410ec66a09 (diff) | |
download | tangerine-consensus-7e9d2db5576d697b578669c935b2e7bbf9422ec7.tar tangerine-consensus-7e9d2db5576d697b578669c935b2e7bbf9422ec7.tar.gz tangerine-consensus-7e9d2db5576d697b578669c935b2e7bbf9422ec7.tar.bz2 tangerine-consensus-7e9d2db5576d697b578669c935b2e7bbf9422ec7.tar.lz tangerine-consensus-7e9d2db5576d697b578669c935b2e7bbf9422ec7.tar.xz tangerine-consensus-7e9d2db5576d697b578669c935b2e7bbf9422ec7.tar.zst tangerine-consensus-7e9d2db5576d697b578669c935b2e7bbf9422ec7.zip |
core: tune performance (#73)
- Avoid using recursive function in critical path.
- Do not write through when using levelDB. Things put to
levelDB would be safe from panic even we didn't force
to write through every time.
- Dump count of confirmed blocks proposed by self.
- Avoid allocating variables in loop.
- Return length of acking node set, we only need that
when total ordering.
- Fix potential bug: make sure win records updated when
acking height vectors of candidates are changed.
- Keep dirty validators in slice.
- Add cache for objects to ease the pressure to garbage
collector.
- Cache global acking status when total ordering.
- Add method to recycle blocks.
- Marshal JSON should be called once for each broadcast.
- Make updateWinRecord called in parallel.
- Log average / deviation of latencies when simulation
finished.
Diffstat (limited to 'core/types')
-rw-r--r-- | core/types/block.go | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/core/types/block.go b/core/types/block.go index 92b0f8a..78548b4 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -22,12 +22,44 @@ package types import ( "bytes" "fmt" + "sync" "time" "github.com/dexon-foundation/dexon-consensus-core/common" "github.com/dexon-foundation/dexon-consensus-core/crypto" ) +var ( + // blockPool is the blocks cache to reuse allocated blocks. + blockPool = sync.Pool{ + New: func() interface{} { + return &Block{} + }, + } +) + +// RecycleBlock put unused block into cache, which might be reused if +// not garbage collected. +func RecycleBlock(b *Block) { + blockPool.Put(b) +} + +// NewBlock initiate a block. +func NewBlock() (b *Block) { + b = blockPool.Get().(*Block) + if b.Acks != nil { + for k := range b.Acks { + delete(b.Acks, k) + } + } + if b.Timestamps != nil { + for k := range b.Timestamps { + delete(b.Timestamps, k) + } + } + return +} + // Block represents a single event broadcasted on the network. type Block struct { ProposerID ValidatorID `json:"proposer_id"` @@ -71,27 +103,29 @@ func (b *Block) String() string { } // Clone returns a deep copy of a block. -func (b *Block) Clone() *Block { - bcopy := &Block{ - ProposerID: b.ProposerID, - ParentHash: b.ParentHash, - Hash: b.Hash, - Height: b.Height, - Timestamps: make(map[ValidatorID]time.Time), - Acks: make(map[common.Hash]struct{}), - Signature: b.Signature.Clone(), - Notary: Notary{ - Timestamp: b.Notary.Timestamp, - Height: b.Notary.Height, - }, +func (b *Block) Clone() (bcopy *Block) { + bcopy = NewBlock() + bcopy.ProposerID = b.ProposerID + bcopy.ParentHash = b.ParentHash + bcopy.Hash = b.Hash + bcopy.Height = b.Height + bcopy.Signature = b.Signature.Clone() + bcopy.Notary.Timestamp = b.Notary.Timestamp + bcopy.Notary.Height = b.Notary.Height + if bcopy.Timestamps == nil { + bcopy.Timestamps = make( + map[ValidatorID]time.Time, len(b.Timestamps)) } for k, v := range b.Timestamps { bcopy.Timestamps[k] = v } + if bcopy.Acks == nil { + bcopy.Acks = make(map[common.Hash]struct{}, len(b.Acks)) + } for k, v := range b.Acks { bcopy.Acks[k] = v } - return bcopy + return } // IsGenesis checks if the block is a genesisBlock |