Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

Commit

Permalink
x/evm/keeper: save 24B with Go in-condition variable idiom
Browse files Browse the repository at this point in the history
The prior code doubly invoked (*ethereum/go-ethereum/core/types.Transaction).To()
which is quite expensive, and firstly copies 20 bytes each time, then
that gets rounded up to the proper size class/pointer alignment so on
64-bit machines 20B -> 24B.

Isolating a benchmark for this code per issue #826 shows this saves
quite a bit of bytes and some nano seconds which all count up towards
the transactions per seconds being processed:

```shell
$ benchstat before.txt after.txt
name        old time/op    new time/op    delta
CopyAddr-8    38.4ns ± 3%    19.3ns ± 3%  -49.66%  (p=0.000 n=10+10)

name        old alloc/op   new alloc/op   delta
CopyAddr-8     48.0B ± 0%     24.0B ± 0%  -50.00%  (p=0.000 n=10+10)

name        old allocs/op  new allocs/op  delta
CopyAddr-8      2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.000 n=10+10)
```

Fixes #826
  • Loading branch information
odeke-em committed Dec 13, 2021
1 parent 876d9cf commit 013ce93
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
33 changes: 33 additions & 0 deletions x/evm/keeper/benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,36 @@ func BenchmarkDeepContextStack10(b *testing.B) {
func BenchmarkDeepContextStack13(b *testing.B) {
DoBenchmarkDeepContextStack(b, 13)
}

func before() *big.Int {
b2 := new(big.Int).SetUint64(2)
return new(big.Int).Mul(b2, new(big.Int).SetUint64(34))
}

func after() *big.Int {
b2 := new(big.Int).SetUint64(2)
return b2
return b2.Mul(b2, new(big.Int).SetUint64(34))
}

var sink interface{}

func BenchmarkMulBefore(b *testing.B) {
for i := 0; i < b.N; i++ {
sink = before()
}
if sink == nil {
b.Fatal("Benchmark did not run")
}
sink = (interface{})(nil)
}

func BenchmarkMulAfter(b *testing.B) {
for i := 0; i < b.N; i++ {
sink = after()
}
if sink == nil {
b.Fatal("Benchmark did not run")
}
sink = (interface{})(nil)
}
4 changes: 2 additions & 2 deletions x/evm/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
attrs = append(attrs, sdk.NewAttribute(types.AttributeKeyTxHash, hash.String()))
}

if tx.To() != nil {
attrs = append(attrs, sdk.NewAttribute(types.AttributeKeyRecipient, tx.To().Hex()))
if to := tx.To(); to != nil {
attrs = append(attrs, sdk.NewAttribute(types.AttributeKeyRecipient, to.Hex()))
}

if response.Failed() {
Expand Down
5 changes: 4 additions & 1 deletion x/evm/keeper/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -623,12 +623,15 @@ func (k *Keeper) Empty(addr common.Address) bool {

codeHash = common.HexToHash(ethAccount.CodeHash).Bytes()
}
if nonce == 0 {
return false
}

balance := k.GetBalance(addr)
hasZeroBalance := balance.Sign() == 0
hasEmptyCodeHash := bytes.Equal(codeHash, types.EmptyCodeHash)

return hasZeroBalance && nonce == 0 && hasEmptyCodeHash
return hasZeroBalance && hasEmptyCodeHash
}

// ----------------------------------------------------------------------------
Expand Down

0 comments on commit 013ce93

Please sign in to comment.