Skip to content

Commit

Permalink
core/vm: add RB Tree EVM benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
Francesco4203 committed Jul 8, 2024
1 parent 265bf11 commit 9051408
Showing 1 changed file with 112 additions and 0 deletions.
112 changes: 112 additions & 0 deletions core/vm/evm_benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
)
Expand Down Expand Up @@ -330,3 +331,114 @@ func BenchmarkEvmMulticallErcTransfer(b *testing.B) {

benchmarkEVM(b, &suite)
}

func BenchmarkEVMRedBlackTree(b *testing.B) {
// Create random array of numbers and options
// The "random" values are generated using a fixed seed for accurate comparison
n := 10000
bound := 1000
var numbers []*big.Int
var options []*big.Int
var args []interface{}
for i := 0; i < n; i++ {
rng := rand.New(rand.NewSource(int64(i)))
numbers = append(numbers, big.NewInt(int64(rng.Intn(bound))+1))
options = append(options, big.NewInt(int64(rng.Intn(2)+1)))
}
args = append(args, numbers)
args = append(args, options)

// Pack data for ABI
parsedABI, err := abi.JSON(strings.NewReader(
`
[
{
"inputs": [
{
"internalType": "uint256[]",
"name": "numbers",
"type": "uint256[]"
},
{
"internalType": "uint256[]",
"name": "options",
"type": "uint256[]"
}
],
"name": "process",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
`,
))
if err != nil {
b.Fatalf("Failed to parse ABI: %v", err)
}
data, err := parsedABI.Pack("process", args...)
if err != nil {
b.Fatalf("Failed to pack data for ABI: %v", err)
}

// Setup EVM to run contract
/*
pragma solidity ^0.8.18;
...
// RBTree library - https://github.com/Vectorized/solady/blob/29d61c504425519c6deddc3e12c2e039ad43e8e3/test/RedBlackTree.t.sol#L4
...
contract OpcodeTest {
using RedBlackTreeLib for *;
RedBlackTreeLib.Tree tree;
function process(uint256[] memory numbers, uint256[] memory options) external {
for (uint256 i = 0; i < numbers.length; i++) {
uint256 option = options[i];
uint256 number = numbers[i];
if (option == 1) {
if (!tree.exists(number)) {
tree.insert(number);
}
} else if (option == 2) {
if (tree.exists(number)) {
tree.remove(number);
}
}
}
}
}
*/
contractString :=
"608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e476ea014610030575b600080fd5b61004361003e366004610987565b610045565b005b60005b82518110156100e1576000828281518110610065576100656109f0565b602002602001015190506000848381518110610083576100836109f0565b60200260200101519050816001036100b4576100a06000826100e6565b6100af576100af6000826100ff565b6100d7565b816002036100d7576100c76000826100e6565b156100d7576100d760008261011c565b5050600101610048565b505050565b6000806100f38484610128565b15159695505050505050565b600061010b83836101b0565b905080156100e1576100e1816101de565b600061010b83836101e8565b600080808361013e5761013e63c94f18776101de565b846020526801dc27bb5462fdadcb600052604060002060201b9250601f600152825460801c5b80156101a857809250808417548060601c806101865750848217638000000017545b8681036101975784935050506101a8565b8611511c637fffffff169050610164565b509250925092565b6000806000806101c08686610128565b9250925092506101d4838383886000610215565b9695505050505050565b806000526004601cfd5b60008060006101f78585610128565b925050915061020c8260008360006001610215565b95945050505050565b6000610896565b8082175480851c637fffffff16603e82901c637fffffff168382175480871c637fffffff16801561025f578086178054637fffffff603e1b1916603e89901b1790555b8261026d57836000526102a5565b8583178054808a1c637fffffff16890361029557637fffffff8a1b1916858a1b1790556102a5565b637fffffff8b1b1916858b1b1790555b637fffffff603e1b19637fffffff808b1b19969096169190991b178816603e84811b919091178787175593871b199716921b91909117949094169190921b17911755565b600083156102fc575063bb33e6ac6104b4565b600160205160801c01637fffffff81111561031e5763ed732d0c9150506104b4565b8060801b60205283603e1b6001605d1b178184176001600160a01b03881161034d57818860601b179150610357565b8763800000008217555b558361036657806000526103ab565b83831780548060601c8061037e575063800000008217545b80891061039e5750673fffffff800000001916601f83901b1790556103ab565b50637fffffff1916821790555b93506001605d1b5b60005185146104a55782851754603e1c637fffffff16808417548281166103db5750506104a5565b603e81901c637fffffff1685811754601f637fffffff8216851402601f811882821c637fffffff16808a175480891661047e5786841c637fffffff168d0361042c57879c5061042c84848f8e61021c565b8a8d1754603e1c637fffffff169750878b1754965088198716888c175561045a603e88637fffffff911c1690565b8b811780548b17905595506104718385888e61021c565b50505050505050506103b3565b88198716888c175588198116828c17555050505084811782881755508097505050506103b3565b60005183178119815416815550505b949350505050565b6001605d1b5b60005183146105fc5782821754808216156104dd57506105fc565b603e81901c637fffffff1683811754909150601f637fffffff8216861402601f811882821c637fffffff1680871754808716156105425786198116828917558685178689175561052f8484888b61021c565b505085841754821c637fffffff16808717545b80831c637fffffff168881175482861c637fffffff16808b17548083178b1661057b5750505050861790871755509194506104c2915050565b808b166105c4578a198316848d17558a8517868d175561059d8789888f61021c565b8b8a1754881c637fffffff168c811754909650945084881c637fffffff169150818c175490505b898c175498508885188b168518868d17558a1989168a8d17558a198116828d17555050505050506105f78282868961021c565b505050505b9117805491199091169055565b8161061657505060005250565b178054637fffffff601f81831695909514159490940293841b19169190921b179055565b600060205160801c831115610654575063ccd52fbc610890565b82610664575063b113638a610890565b818317548390637fffffff601f82901c81169116808202156106a0578192505b84831754637fffffff168061069957506106a0565b9250610684565b505082811754637fffffff81168015601f0282901c637fffffff169050603e82901c637fffffff168186178054637fffffff603e1b1916603e83901b1790556106eb84838389610609565b50858314610765578486175461070d8785603e84901c637fffffff1689610609565b637fffffff811686178054637fffffff603e1b1916603e86901b179055601f81901c637fffffff1686178054637fffffff603e1b1916603e86901b17905582186bffffffffffffffffffffffff168218858417559194915b816001605d1b1661077a5761077a81866104bc565b505060205160801c808417548060601c60008161079f57505063800000008583171754805b8487175460601c6000816107bb57505063800000008786171754805b8184146108665784878a17558083146107da5782878a17638000000017555b603e85901c637fffffff16806107f35787600052610814565b8981178054637fffffff8082168a1415601f028b811b91901b199091161790555b50601f85901c637fffffff16801561083e57808a178054637fffffff603e1b1916603e8a901b1790555b50637fffffff8516801561086457808a178054637fffffff603e1b1916603e8a901b1790555b505b50506000848817558015610881576000848817638000000017555b5050506000190160801b602052505b92915050565b386000528554601052816108b7576108b0838587896102e9565b90506108c4565b6108c1848761063a565b90505b601051865595945050505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126108f957600080fd5b813567ffffffffffffffff811115610913576109136108d2565b8060051b604051601f19603f830116810181811067ffffffffffffffff82111715610940576109406108d2565b60405291825260208185018101929081018684111561095e57600080fd5b6020860192505b8383101561097d578235815260209283019201610965565b5095945050505050565b6000806040838503121561099a57600080fd5b823567ffffffffffffffff8111156109b157600080fd5b6109bd858286016108e8565b925050602083013567ffffffffffffffff8111156109da57600080fd5b6109e6858286016108e8565b9150509250929050565b634e487b7160e01b600052603260045260246000fdfea264697066735822122060f7fd286cb5b1331bc5d1520a171917f649e24017f29882e087085a042e6a0c64736f6c634300081a0033"
statedb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
if err != nil {
b.Fatal(err)
}
evm := NewEVM(
BlockContext{
BlockNumber: common.Big0,
Transfer: func(_ StateDB, _, _ common.Address, _ *big.Int) {},
PublishEvents: make(PublishEventsMap),
CurrentTransaction: types.NewTx(&types.LegacyTx{}),
},
TxContext{},
statedb,
&params.ChainConfig{
LondonBlock: common.Big0,
},
Config{},
)

testContract := common.Hex2Bytes(contractString)
testAddress := common.BigToAddress(big.NewInt(0x201))

statedb.SetCode(testAddress, testContract)

b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _, err = evm.Call(AccountRef(testAddress), testAddress, data, 100_000_000_000, big.NewInt(0))
if err != nil {
b.Fatal(err)
}
}
}

0 comments on commit 9051408

Please sign in to comment.