github.com/klaytn/klaytn@v1.12.1/blockchain/types/encode_benchmark_test.go (about)

     1  // Copyright 2019 The klaytn Authors
     2  // This file is part of the klaytn library.
     3  //
     4  // The klaytn library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The klaytn library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package types
    18  
    19  import (
    20  	"bytes"
    21  	"testing"
    22  
    23  	"github.com/klaytn/klaytn/blockchain/types/accountkey"
    24  	"github.com/klaytn/klaytn/rlp"
    25  )
    26  
    27  func BenchmarkTxEncode(b *testing.B) {
    28  	txs := []struct {
    29  		Name string
    30  		tx   TxInternalData
    31  	}{
    32  		{"OriginalTx", genLegacyTransaction()},
    33  		{"ValueTransfer", genValueTransferTransaction()},
    34  		{"FeeDelegatedValueTransfer", genFeeDelegatedValueTransferTransaction()},
    35  		{"FeeDelegatedValueTransferWithRatio", genFeeDelegatedValueTransferWithRatioTransaction()},
    36  		{"AccountUpdate", genAccountUpdateTransaction()},
    37  		{"SmartContractDeploy", genSmartContractDeployTransaction()},
    38  		{"SmartContractExecution", genSmartContractExecutionTransaction()},
    39  		{"ChainDataTx", genChainDataTransaction()},
    40  	}
    41  	testcases := []struct {
    42  		Name string
    43  		fn   func(b *testing.B, tx TxInternalData)
    44  	}{
    45  		{"Encode", benchmarkEncode},
    46  		{"EncodeToBytes", benchmarkEncodeToBytes},
    47  		{"EncodeInterfaceSlice", benchmarkInterfaceSlice},
    48  		{"EncodeInterfaceSliceLoop", benchmarkInterfaceSliceLoop},
    49  	}
    50  
    51  	for _, tx := range txs {
    52  		for _, test := range testcases {
    53  			Name := test.Name + "/" + tx.Name
    54  			b.Run(Name, func(b *testing.B) {
    55  				test.fn(b, tx.tx)
    56  			})
    57  		}
    58  	}
    59  }
    60  
    61  func benchmarkEncode(b *testing.B, txInternal TxInternalData) {
    62  	var i int
    63  	tx := &Transaction{data: txInternal}
    64  	b.ResetTimer()
    65  	for i = 0; i < b.N; i++ {
    66  		buffer := new(bytes.Buffer)
    67  		if err := rlp.Encode(buffer, tx); err != nil {
    68  			b.Fatal(err)
    69  		}
    70  	}
    71  	b.StopTimer()
    72  }
    73  
    74  func benchmarkEncodeToBytes(b *testing.B, txInternal TxInternalData) {
    75  	var i int
    76  	tx := &Transaction{data: txInternal}
    77  	b.ResetTimer()
    78  	for i = 0; i < b.N; i++ {
    79  		_, err := rlp.EncodeToBytes(tx)
    80  		if err != nil {
    81  			b.Fatal(err)
    82  		}
    83  	}
    84  	b.StopTimer()
    85  }
    86  
    87  func benchmarkInterfaceSlice(b *testing.B, txInternal TxInternalData) {
    88  	var i int
    89  	b.ResetTimer()
    90  	for i = 0; i < b.N; i++ {
    91  		ifs := getInterfaceSlice(txInternal)
    92  		_, err := rlp.EncodeToBytes(ifs)
    93  		if err != nil {
    94  			b.Fatal(err)
    95  		}
    96  	}
    97  	b.StopTimer()
    98  }
    99  
   100  func benchmarkInterfaceSliceLoop(b *testing.B, txInternal TxInternalData) {
   101  	var i int
   102  	b.ResetTimer()
   103  	for i = 0; i < b.N; i++ {
   104  		buffer := new(bytes.Buffer)
   105  		ifs := getInterfaceSlice(txInternal)
   106  		for _, it := range ifs {
   107  			if err := rlp.Encode(buffer, it); err != nil {
   108  				b.Fatal(err)
   109  			}
   110  		}
   111  	}
   112  	b.StopTimer()
   113  }
   114  
   115  func getInterfaceSlice(tx TxInternalData) []interface{} {
   116  	return tx.(SliceMaker).MakeInterfaceSlice()
   117  }
   118  
   119  type SliceMaker interface {
   120  	MakeInterfaceSlice() []interface{}
   121  }
   122  
   123  func (v *TxInternalDataLegacy) MakeInterfaceSlice() []interface{} {
   124  	return []interface{}{
   125  		v.Type(),
   126  		v.AccountNonce,
   127  		v.Price,
   128  		v.GasLimit,
   129  		v.Recipient,
   130  		v.Amount,
   131  		v.Payload,
   132  		v.V,
   133  		v.R,
   134  		v.S,
   135  	}
   136  }
   137  
   138  func (v *TxInternalDataValueTransfer) MakeInterfaceSlice() []interface{} {
   139  	return []interface{}{
   140  		v.Type(),
   141  		v.AccountNonce,
   142  		v.Price,
   143  		v.GasLimit,
   144  		v.Recipient,
   145  		v.Amount,
   146  		v.From,
   147  		v.TxSignatures,
   148  	}
   149  }
   150  
   151  func (v *TxInternalDataFeeDelegatedValueTransfer) MakeInterfaceSlice() []interface{} {
   152  	return []interface{}{
   153  		v.Type(),
   154  		v.AccountNonce,
   155  		v.Price,
   156  		v.GasLimit,
   157  		v.Recipient,
   158  		v.Amount,
   159  		v.From,
   160  		v.TxSignatures,
   161  		v.FeePayer,
   162  		v.FeePayerSignatures,
   163  	}
   164  }
   165  
   166  func (v *TxInternalDataFeeDelegatedValueTransferWithRatio) MakeInterfaceSlice() []interface{} {
   167  	return []interface{}{
   168  		v.Type(),
   169  		v.AccountNonce,
   170  		v.Price,
   171  		v.GasLimit,
   172  		v.Recipient,
   173  		v.Amount,
   174  		v.From,
   175  		v.FeeRatio,
   176  		v.TxSignatures,
   177  		v.FeePayer,
   178  		v.FeePayerSignatures,
   179  	}
   180  }
   181  
   182  func (v *TxInternalDataAccountCreation) MakeInterfaceSlice() []interface{} {
   183  	serializer := accountkey.NewAccountKeySerializerWithAccountKey(v.Key)
   184  	keyEnc, _ := rlp.EncodeToBytes(serializer)
   185  	return []interface{}{
   186  		v.Type(),
   187  		v.AccountNonce,
   188  		v.Price,
   189  		v.GasLimit,
   190  		v.Recipient,
   191  		v.Amount,
   192  		v.From,
   193  		v.HumanReadable,
   194  		keyEnc,
   195  		v.TxSignatures,
   196  	}
   197  }
   198  
   199  func (v *TxInternalDataAccountUpdate) MakeInterfaceSlice() []interface{} {
   200  	serializer := accountkey.NewAccountKeySerializerWithAccountKey(v.Key)
   201  	keyEnc, _ := rlp.EncodeToBytes(serializer)
   202  	return []interface{}{
   203  		v.Type(),
   204  		v.AccountNonce,
   205  		v.Price,
   206  		v.GasLimit,
   207  		v.From,
   208  		keyEnc,
   209  		v.TxSignatures,
   210  	}
   211  }
   212  
   213  func (v *TxInternalDataSmartContractDeploy) MakeInterfaceSlice() []interface{} {
   214  	return []interface{}{
   215  		v.Type(),
   216  		v.AccountNonce,
   217  		v.Price,
   218  		v.GasLimit,
   219  		v.Recipient,
   220  		v.Amount,
   221  		v.From,
   222  		v.Payload,
   223  		v.HumanReadable,
   224  		v.TxSignatures,
   225  	}
   226  }
   227  
   228  func (v *TxInternalDataSmartContractExecution) MakeInterfaceSlice() []interface{} {
   229  	return []interface{}{
   230  		v.Type(),
   231  		v.AccountNonce,
   232  		v.Price,
   233  		v.GasLimit,
   234  		v.Recipient,
   235  		v.Amount,
   236  		v.From,
   237  		v.Payload,
   238  		v.TxSignatures,
   239  	}
   240  }
   241  
   242  func (v *TxInternalDataChainDataAnchoring) MakeInterfaceSlice() []interface{} {
   243  	return []interface{}{
   244  		v.Type(),
   245  		v.AccountNonce,
   246  		v.Price,
   247  		v.GasLimit,
   248  		v.From,
   249  		v.Payload,
   250  		v.TxSignatures,
   251  	}
   252  }