Commit 0dc0cad7 authored by vicotor's avatar vicotor

add benchmark

parent 27019cdf
package main
import (
"flag"
"github.com/exchain/go-exchain/exchain"
nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
"google.golang.org/protobuf/proto"
"log"
"time"
)
var (
txCount = flag.Int("txcount", 100000, "tx count")
blockTxCount = flag.Int("btx", 10000, "block tx count")
loopCount = flag.Int("loopcount", 100, "loop count")
)
// do benchmark test.
func main() {
flag.Parse()
if *loopCount <= 0 {
*loopCount = 1
}
// do tx serialize benchmark test.
if *txCount > 0 {
benchLimitTx()
benchMarketTx()
benchCancelTx()
}
if *blockTxCount > 0 {
benchBlock()
}
}
func benchLimitTx() {
count := *txCount
txs := exchain.TestMakeTxs(nebulav1.TxType_LimitTx, count)
t1 := time.Now()
// benchmark limit tx serialize and unserialize.
for i := 0; i < *loopCount; i++ {
tx := txs.Txs[i%count]
d, err := proto.Marshal(tx)
if err != nil {
panic(err)
}
ntx := new(nebulav1.Transaction)
err = proto.Unmarshal(d, ntx)
if ntx.TxType != tx.TxType {
panic("unserialize tx type error")
}
}
tps := float64(1) * float64(*loopCount) * 1000 / float64(time.Since(t1).Milliseconds())
log.Printf("limit tx serialize and unserialize cost: %v, tx count:%d, loop count: %d, tps:%f\n", time.Since(t1), count, *loopCount, tps)
}
func benchMarketTx() {
count := *txCount
txs := exchain.TestMakeTxs(nebulav1.TxType_MarketTx, count)
t1 := time.Now()
// benchmark market tx serialize and unserialize.
for i := 0; i < *loopCount; i++ {
tx := txs.Txs[i%count]
d, err := proto.Marshal(tx)
if err != nil {
panic(err)
}
ntx := new(nebulav1.Transaction)
err = proto.Unmarshal(d, ntx)
if ntx.TxType != tx.TxType {
panic("unserialize tx type error")
}
}
tps := float64(1) * float64(*loopCount) * 1000 / float64(time.Since(t1).Milliseconds())
log.Printf("market tx serialize and unserialize cost: %v, tx count:%d, loop count: %d, tps:%f\n", time.Since(t1), count, *loopCount, tps)
}
func benchCancelTx() {
count := *txCount
txs := exchain.TestMakeTxs(nebulav1.TxType_CancelTx, count)
t1 := time.Now()
// benchmark cancel tx serialize and unserialize.
for i := 0; i < *loopCount; i++ {
tx := txs.Txs[i%count]
d, err := proto.Marshal(tx)
if err != nil {
panic(err)
}
ntx := new(nebulav1.Transaction)
err = proto.Unmarshal(d, ntx)
if ntx.TxType != tx.TxType {
panic("unserialize tx type error")
}
}
tps := float64(1) * float64(*loopCount) * 1000 / float64(time.Since(t1).Milliseconds())
log.Printf("cancel tx serialize and unserialize cost: %v, tx count:%d, loop count: %d, tps:%f\n", time.Since(t1), count, *loopCount, tps)
}
func benchBlock() {
count := *blockTxCount
blocks := make([]*nebulav1.Block, 0, *loopCount)
for i := 0; i < *loopCount; i++ {
blocks = append(blocks, exchain.TestMakeBlock(count))
}
t1 := time.Now()
// benchmark block serialize and unserialize.
for i := 0; i < *loopCount; i++ {
b := blocks[i]
d, err := proto.Marshal(b)
if err != nil {
panic(err)
}
nb := new(nebulav1.Block)
err = proto.Unmarshal(d, nb)
if len(nb.Transactions.Txs) != len(b.Transactions.Txs) {
panic("unserialize block error")
}
}
tps := float64(1) * float64(*loopCount) * 1000 / float64(time.Since(t1).Milliseconds())
log.Printf("block serialize and unserialize cost: %v, tx count:%d, loop count: %d, tps:%f\n", time.Since(t1), count, *loopCount, tps)
}
...@@ -3,134 +3,16 @@ package exchain ...@@ -3,134 +3,16 @@ package exchain
import ( import (
nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1" nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"github.com/google/uuid"
"github.com/holiman/uint256"
"github.com/oklog/ulid"
"math/rand"
"testing" "testing"
"time"
) )
var (
randReader = rand.New(rand.NewSource(time.Now().UnixNano()))
)
func getHash() []byte {
d := make([]byte, 32)
for i := 0; i < 32; i++ {
d[i] = byte(rand.Intn(128))
}
return d
}
func getAddr() []byte {
d := make([]byte, 20)
for i := 0; i < 20; i++ {
d[i] = byte(rand.Intn(128))
}
return d
}
func makeBlock(txcount int) *nebulav1.Block {
block := new(nebulav1.Block)
block.Header = new(nebulav1.BlockHeader)
block.Header.Height = uint64(rand.Intn(1000000))
block.Header.Hash = getHash()
block.Header.ParentHash = getHash()
block.Header.Proposer = getAddr()
block.Header.Timestamp = uint64(time.Now().UnixNano() / 1000 / 1000)
txs := randomTxs(txcount)
block.Transactions = &txs
return block
}
func makeLimitTx() *nebulav1.LimitOrderTransaction {
price := rand.Intn(1000) + 500
tx := new(nebulav1.LimitOrderTransaction)
tx.Pair = "eth_usdt"
tx.Side = nebulav1.OrderSide_BUY
tx.Price = uint256.NewInt(uint64(price)).Bytes()
tx.Quantity = uint256.NewInt(uint64(rand.Intn(1000) + 100)).Bytes()
return tx
}
func makeMarketTx() *nebulav1.MarketOrderTransaction {
tx := new(nebulav1.MarketOrderTransaction)
tx.Pair = "eth_usdt"
tx.Side = nebulav1.OrderSide_BUY
tx.Quantity = uint256.NewInt(uint64(rand.Intn(1000) + 100)).Bytes()
return tx
}
func makeCancelTx() *nebulav1.CancelOrderTransaction {
tx := new(nebulav1.CancelOrderTransaction)
tx.OrderId = uuid.NewString()
return tx
}
func makeTx(tp nebulav1.TxType) *nebulav1.Transaction {
tx := new(nebulav1.Transaction)
tx.Proxy = false
uld, err := ulid.New(ulid.Timestamp(time.Now()), randReader)
if err != nil {
panic(err)
}
tx.Nonce = uld[:]
tx.Signature = &nebulav1.Signature{
// random 32 bytes
R: []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20},
S: []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20},
V: 1,
}
switch tp {
case nebulav1.TxType_LimitTx:
txdata := makeLimitTx()
tx.TxType = nebulav1.TxType_LimitTx
tx.Tx = &nebulav1.Transaction_LimitTx{LimitTx: txdata}
case nebulav1.TxType_MarketTx:
txdata := makeMarketTx()
tx.TxType = nebulav1.TxType_MarketTx
tx.Tx = &nebulav1.Transaction_MarketTx{MarketTx: txdata}
case nebulav1.TxType_CancelTx:
txdata := makeCancelTx()
tx.TxType = nebulav1.TxType_CancelTx
tx.Tx = &nebulav1.Transaction_CancelTx{CancelTx: txdata}
default:
panic("unknown tx type")
}
return tx
}
func makeTxs(tp nebulav1.TxType, count int) nebulav1.TransactionList {
txlist := nebulav1.TransactionList{
Txs: make([]*nebulav1.Transaction, 0, count),
}
for i := 0; i < count; i++ {
txlist.Txs = append(txlist.Txs, makeTx(tp))
}
return txlist
}
func randomTxs(count int) nebulav1.TransactionList {
txlist := nebulav1.TransactionList{
Txs: make([]*nebulav1.Transaction, 0, count),
}
for i := 0; i < count; i++ {
tp := nebulav1.TxType_LimitTx + nebulav1.TxType(rand.Intn(3))
txlist.Txs = append(txlist.Txs, makeTx(tp))
}
return txlist
}
// todo: tx press test. // todo: tx press test.
// limit, market, cancel 100w, each block 10w. // limit, market, cancel 100w, each block 10w.
// serialize and unserialize. // serialize and unserialize.
func BenchmarkLimitTxSerialize(b *testing.B) { func BenchmarkLimitTxSerialize(b *testing.B) {
b.StopTimer() b.StopTimer()
count := 100000 count := 100000
txs := makeTxs(nebulav1.TxType_LimitTx, count) txs := TestMakeTxs(nebulav1.TxType_LimitTx, count)
b.StartTimer() b.StartTimer()
// benchmark limit tx serialize and unserialize. // benchmark limit tx serialize and unserialize.
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
...@@ -150,7 +32,7 @@ func BenchmarkLimitTxSerialize(b *testing.B) { ...@@ -150,7 +32,7 @@ func BenchmarkLimitTxSerialize(b *testing.B) {
func BenchmarkMarketTxSerialize(b *testing.B) { func BenchmarkMarketTxSerialize(b *testing.B) {
b.StopTimer() b.StopTimer()
count := 100000 count := 100000
txs := makeTxs(nebulav1.TxType_MarketTx, count) txs := TestMakeTxs(nebulav1.TxType_MarketTx, count)
b.StartTimer() b.StartTimer()
// benchmark market tx serialize and unserialize. // benchmark market tx serialize and unserialize.
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
...@@ -170,7 +52,7 @@ func BenchmarkMarketTxSerialize(b *testing.B) { ...@@ -170,7 +52,7 @@ func BenchmarkMarketTxSerialize(b *testing.B) {
func BenchmarkCancelTxSerialize(b *testing.B) { func BenchmarkCancelTxSerialize(b *testing.B) {
b.StopTimer() b.StopTimer()
count := 100000 count := 100000
txs := makeTxs(nebulav1.TxType_CancelTx, count) txs := TestMakeTxs(nebulav1.TxType_CancelTx, count)
b.StartTimer() b.StartTimer()
// benchmark cancel tx serialize and unserialize. // benchmark cancel tx serialize and unserialize.
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
...@@ -190,7 +72,7 @@ func BenchmarkCancelTxSerialize(b *testing.B) { ...@@ -190,7 +72,7 @@ func BenchmarkCancelTxSerialize(b *testing.B) {
func BenchmarkTxlistSerialize(b *testing.B) { func BenchmarkTxlistSerialize(b *testing.B) {
b.StopTimer() b.StopTimer()
count := 1000000 count := 1000000
txs := randomTxs(count) txs := TestRandomTxs(count)
b.StartTimer() b.StartTimer()
// benchmark tx list serialize and unserialize. // benchmark tx list serialize and unserialize.
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
...@@ -211,7 +93,7 @@ func BenchmarkBlockSerialize(b *testing.B) { ...@@ -211,7 +93,7 @@ func BenchmarkBlockSerialize(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
b.StopTimer() b.StopTimer()
txcount := 100000 txcount := 100000
block := makeBlock(txcount) block := TestMakeBlock(txcount)
b.StartTimer() b.StartTimer()
d, err := proto.Marshal(block) d, err := proto.Marshal(block)
if err != nil { if err != nil {
......
package exchain
import (
nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
"github.com/google/uuid"
"github.com/holiman/uint256"
"github.com/oklog/ulid/v2"
"math/rand"
"time"
)
var (
randReader = rand.New(rand.NewSource(time.Now().UnixNano()))
)
func getHash() []byte {
d := make([]byte, 32)
for i := 0; i < 32; i++ {
d[i] = byte(rand.Intn(128))
}
return d
}
func getAddr() []byte {
d := make([]byte, 20)
for i := 0; i < 20; i++ {
d[i] = byte(rand.Intn(128))
}
return d
}
func TestMakeBlock(txcount int) *nebulav1.Block {
block := new(nebulav1.Block)
block.Header = new(nebulav1.BlockHeader)
block.Header.Height = uint64(rand.Intn(1000000))
block.Header.Hash = getHash()
block.Header.ParentHash = getHash()
block.Header.Proposer = getAddr()
block.Header.Timestamp = uint64(time.Now().UnixNano() / 1000 / 1000)
txs := TestRandomTxs(txcount)
block.Transactions = &txs
return block
}
func TestMakeLimitTx() *nebulav1.LimitOrderTransaction {
price := rand.Intn(1000) + 500
tx := new(nebulav1.LimitOrderTransaction)
tx.Pair = "eth_usdt"
tx.Side = nebulav1.OrderSide_BUY
tx.Price = uint256.NewInt(uint64(price)).Bytes()
tx.Quantity = uint256.NewInt(uint64(rand.Intn(1000) + 100)).Bytes()
return tx
}
func TestMakeMarketTx() *nebulav1.MarketOrderTransaction {
tx := new(nebulav1.MarketOrderTransaction)
tx.Pair = "eth_usdt"
tx.Side = nebulav1.OrderSide_BUY
tx.Quantity = uint256.NewInt(uint64(rand.Intn(1000) + 100)).Bytes()
return tx
}
func TestMakeCancelTx() *nebulav1.CancelOrderTransaction {
tx := new(nebulav1.CancelOrderTransaction)
tx.OrderId = uuid.NewString()
return tx
}
func TestMakeTx(tp nebulav1.TxType) *nebulav1.Transaction {
tx := new(nebulav1.Transaction)
tx.Proxy = false
uld, err := ulid.New(ulid.Timestamp(time.Now()), randReader)
if err != nil {
panic(err)
}
tx.Nonce = uld[:]
tx.Signature = &nebulav1.Signature{
// random 32 bytes
R: getHash(),
S: getHash(),
V: 1,
}
switch tp {
case nebulav1.TxType_LimitTx:
txdata := TestMakeLimitTx()
tx.TxType = nebulav1.TxType_LimitTx
tx.Tx = &nebulav1.Transaction_LimitTx{LimitTx: txdata}
case nebulav1.TxType_MarketTx:
txdata := TestMakeMarketTx()
tx.TxType = nebulav1.TxType_MarketTx
tx.Tx = &nebulav1.Transaction_MarketTx{MarketTx: txdata}
case nebulav1.TxType_CancelTx:
txdata := TestMakeCancelTx()
tx.TxType = nebulav1.TxType_CancelTx
tx.Tx = &nebulav1.Transaction_CancelTx{CancelTx: txdata}
default:
panic("unknown tx type")
}
return tx
}
func TestMakeTxs(tp nebulav1.TxType, count int) nebulav1.TransactionList {
txlist := nebulav1.TransactionList{
Txs: make([]*nebulav1.Transaction, 0, count),
}
for i := 0; i < count; i++ {
txlist.Txs = append(txlist.Txs, TestMakeTx(tp))
}
return txlist
}
func TestRandomTxs(count int) nebulav1.TransactionList {
txlist := nebulav1.TransactionList{
Txs: make([]*nebulav1.Transaction, 0, count),
}
for i := 0; i < count; i++ {
tp := nebulav1.TxType_LimitTx + nebulav1.TxType(rand.Intn(3))
txlist.Txs = append(txlist.Txs, TestMakeTx(tp))
}
return txlist
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment