@@ -16,6 +16,11 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion};
1616use  fastrace:: { collector:: Config ,  prelude:: * } ; 
1717use  fastrace_jaeger:: JaegerReporter ; 
1818use  grevm:: GrevmScheduler ; 
19+ use  metrics:: { SharedString ,  Unit } ; 
20+ use  metrics_util:: { 
21+     debugging:: { DebugValue ,  DebuggingRecorder } , 
22+     CompositeKey ,  MetricKind , 
23+ } ; 
1924use  rand:: Rng ; 
2025use  revm:: primitives:: { alloy_primitives:: U160 ,  Address ,  Env ,  SpecId ,  TransactTo ,  TxEnv ,  U256 } ; 
2126use  std:: { collections:: HashMap ,  sync:: Arc } ; 
@@ -25,49 +30,96 @@ const GIGA_GAS: u64 = 1_000_000_000;
2530#[ global_allocator]  
2631static  GLOBAL :  tikv_jemallocator:: Jemalloc  = tikv_jemallocator:: Jemalloc ; 
2732
33+ fn  get_metrics_counter_value ( 
34+     snapshot :  & HashMap < CompositeKey ,  ( Option < Unit > ,  Option < SharedString > ,  DebugValue ) > , 
35+     name :  & ' static  str , 
36+ )  -> u64  { 
37+     match  snapshot
38+         . get ( & CompositeKey :: new ( MetricKind :: Counter ,  metrics:: Key :: from_static_name ( name) ) ) 
39+     { 
40+         Some ( ( _,  _,  DebugValue :: Counter ( value) ) )  => * value, 
41+         _ => panic ! ( "{:?} not found" ,  name) , 
42+     } 
43+ } 
44+ 
2845fn  bench ( c :  & mut  Criterion ,  name :  & str ,  db :  InMemoryDB ,  txs :  Vec < TxEnv > )  { 
2946    let  mut  env = Env :: default ( ) ; 
3047    env. cfg . chain_id  = NamedChain :: Mainnet . into ( ) ; 
3148    env. block . coinbase  = Address :: from ( U160 :: from ( common:: MINER_ADDRESS ) ) ; 
3249    let  db = Arc :: new ( db) ; 
50+     let  txs = Arc :: new ( txs) ; 
3351
34-     let  mut  group = c. benchmark_group ( name) ; 
52+     let  mut  group = c. benchmark_group ( format ! ( "{}({} txs)" ,   name,  txs . len ( ) ) ) ; 
3553    group. bench_function ( "Origin Sequential" ,  |b| { 
3654        b. iter ( || { 
3755            common:: execute_revm_sequential ( 
3856                black_box ( db. clone ( ) ) , 
3957                black_box ( SpecId :: LATEST ) , 
4058                black_box ( env. clone ( ) ) , 
41-                 black_box ( txs. clone ( ) ) , 
59+                 black_box ( & * txs) , 
4260            ) 
4361        } ) 
4462    } ) ; 
63+ 
64+     let  mut  num_iter:  usize  = 0 ; 
65+     let  mut  execution_time_ns:  u64  = 0 ; 
4566    group. bench_function ( "Grevm Parallel" ,  |b| { 
4667        b. iter ( || { 
68+             num_iter += 1 ; 
69+             let  recorder = DebuggingRecorder :: new ( ) ; 
4770            let  root = Span :: root ( format ! ( "{name} Grevm Parallel" ) ,  SpanContext :: random ( ) ) ; 
4871            let  _guard = root. set_local_parent ( ) ; 
49-             let  executor = GrevmScheduler :: new ( 
50-                 black_box ( SpecId :: LATEST ) , 
51-                 black_box ( env. clone ( ) ) , 
52-                 black_box ( db. clone ( ) ) , 
53-                 black_box ( txs. clone ( ) ) , 
54-             ) ; 
55-             executor. parallel_execute ( ) 
72+             metrics:: with_local_recorder ( & recorder,  || { 
73+                 let  executor = GrevmScheduler :: new ( 
74+                     black_box ( SpecId :: LATEST ) , 
75+                     black_box ( env. clone ( ) ) , 
76+                     black_box ( db. clone ( ) ) , 
77+                     black_box ( txs. clone ( ) ) , 
78+                 ) ; 
79+                 let  _ = executor. parallel_execute ( ) ; 
80+ 
81+                 let  snapshot = recorder. snapshotter ( ) . snapshot ( ) . into_hashmap ( ) ; 
82+                 execution_time_ns +=
83+                     get_metrics_counter_value ( & snapshot,  "grevm.parallel_execute_time" ) ; 
84+                 execution_time_ns += get_metrics_counter_value ( & snapshot,  "grevm.validate_time" ) ; 
85+             } ) ; 
5686        } ) 
5787    } ) ; 
88+     println ! ( 
89+         "{} Grevm Parallel average execution time: {:.2} ms" , 
90+         name, 
91+         execution_time_ns as  f64  / num_iter as  f64  / 1000000.0 
92+     ) ; 
93+ 
94+     let  mut  num_iter:  usize  = 0 ; 
95+     let  mut  execution_time_ns:  u64  = 0 ; 
5896    group. bench_function ( "Grevm Sequential" ,  |b| { 
5997        b. iter ( || { 
98+             num_iter += 1 ; 
99+             let  recorder = DebuggingRecorder :: new ( ) ; 
60100            let  root = Span :: root ( format ! ( "{name} Grevm Sequential" ) ,  SpanContext :: random ( ) ) ; 
61101            let  _guard = root. set_local_parent ( ) ; 
62-             let  executor = GrevmScheduler :: new ( 
63-                 black_box ( SpecId :: LATEST ) , 
64-                 black_box ( env. clone ( ) ) , 
65-                 black_box ( db. clone ( ) ) , 
66-                 black_box ( txs. clone ( ) ) , 
67-             ) ; 
68-             executor. force_sequential_execute ( ) 
102+             metrics:: with_local_recorder ( & recorder,  || { 
103+                 let  executor = GrevmScheduler :: new ( 
104+                     black_box ( SpecId :: LATEST ) , 
105+                     black_box ( env. clone ( ) ) , 
106+                     black_box ( db. clone ( ) ) , 
107+                     black_box ( txs. clone ( ) ) , 
108+                 ) ; 
109+                 let  _ = executor. force_sequential_execute ( ) ; 
110+ 
111+                 let  snapshot = recorder. snapshotter ( ) . snapshot ( ) . into_hashmap ( ) ; 
112+                 execution_time_ns +=
113+                     get_metrics_counter_value ( & snapshot,  "grevm.sequential_execute_time" ) ; 
114+             } ) ; 
69115        } ) 
70116    } ) ; 
117+     println ! ( 
118+         "{} Grevm Sequential average execution time: {:.2} ms" , 
119+         name, 
120+         execution_time_ns as  f64  / num_iter as  f64  / 1000000.0 
121+     ) ; 
122+ 
71123    group. finish ( ) ; 
72124} 
73125
@@ -96,15 +148,19 @@ fn bench_raw_transfers(c: &mut Criterion, db_latency_us: u64) {
96148    ) ; 
97149} 
98150
99- fn  get_account_idx ( num_eoa :   usize ,   hot_start_idx :  usize ,  hot_ratio :  f64 )  -> usize  { 
151+ fn  pick_account_idx ( num_eoa :  usize ,  hot_ratio :  f64 )  -> usize  { 
100152    if  hot_ratio <= 0.0  { 
101153        // Uniform workload 
102-         rand:: random :: < usize > ( )  % num_eoa
103-     }  else  if  rand:: thread_rng ( ) . gen_range ( 0.0 ..1.0 )  < hot_ratio { 
154+         return  rand:: random :: < usize > ( )  % num_eoa; 
155+     } 
156+ 
157+     // Let `hot_ratio` of transactions conducted by 10% of hot accounts 
158+     let  hot_start_idx = ( num_eoa as  f64  *  0.9 )  as  usize ; 
159+     if  rand:: thread_rng ( ) . gen_range ( 0.0 ..1.0 )  < hot_ratio { 
104160        // Access hot 
105161        hot_start_idx + rand:: random :: < usize > ( )  % ( num_eoa - hot_start_idx) 
106162    }  else  { 
107-         rand:: random :: < usize > ( )  % ( num_eoa -  hot_start_idx) 
163+         rand:: random :: < usize > ( )  % hot_start_idx
108164    } 
109165} 
110166
@@ -119,20 +175,17 @@ fn bench_dependent_raw_transfers(
119175    let  mut  db = InMemoryDB :: new ( accounts,  Default :: default ( ) ,  Default :: default ( ) ) ; 
120176    db. latency_us  = db_latency_us; 
121177
122-     // Let 10% of the accounts be hot accounts 
123-     let  hot_start_idx = common:: START_ADDRESS  + ( num_eoa as  f64  *  0.9 )  as  usize ; 
124- 
125178    bench ( 
126179        c, 
127180        "Dependent Raw Transfers" , 
128181        db, 
129182        ( 0 ..block_size) 
130183            . map ( |_| { 
131184                let  from = Address :: from ( U160 :: from ( 
132-                     common:: START_ADDRESS  + get_account_idx ( num_eoa,  hot_start_idx ,  hot_ratio) , 
185+                     common:: START_ADDRESS  + pick_account_idx ( num_eoa,  hot_ratio) , 
133186                ) ) ; 
134187                let  to = Address :: from ( U160 :: from ( 
135-                     common:: START_ADDRESS  + get_account_idx ( num_eoa,  hot_start_idx ,  hot_ratio) , 
188+                     common:: START_ADDRESS  + pick_account_idx ( num_eoa,  hot_ratio) , 
136189                ) ) ; 
137190                TxEnv  { 
138191                    caller :  from, 
@@ -203,12 +256,9 @@ fn benchmark_dependent_erc20(
203256    let  mut  txs = Vec :: with_capacity ( block_size) ; 
204257    let  sca = sca[ 0 ] ; 
205258
206-     // Let 10% of the accounts be hot accounts 
207-     let  hot_start_idx = common:: START_ADDRESS  + ( num_eoa as  f64  *  0.9 )  as  usize ; 
208- 
209259    for  _ in  0 ..block_size { 
210-         let  from = eoa[ get_account_idx ( num_eoa,  hot_start_idx ,  hot_ratio) ] ; 
211-         let  to = eoa[ get_account_idx ( num_eoa,  hot_start_idx ,  hot_ratio) ] ; 
260+         let  from = eoa[ pick_account_idx ( num_eoa,  hot_ratio) ] ; 
261+         let  to = eoa[ pick_account_idx ( num_eoa,  hot_ratio) ] ; 
212262        let  tx = TxEnv  { 
213263            caller :  from, 
214264            transact_to :  TransactTo :: Call ( sca) , 
@@ -250,19 +300,15 @@ fn bench_hybrid(c: &mut Criterion, db_latency_us: u64, num_eoa: usize, hot_ratio
250300        ( GIGA_GAS  as  f64  *  0.2  / erc20:: ESTIMATED_GAS_USED  as  f64 ) . ceil ( )  as  usize ; 
251301    let  num_uniswap = ( GIGA_GAS  as  f64  *  0.2  / uniswap:: ESTIMATED_GAS_USED  as  f64 ) . ceil ( )  as  usize ; 
252302
253-     // Let 10% of the accounts be hot accounts 
254-     let  hot_start_idx = common:: START_ADDRESS  + ( num_eoa as  f64  *  0.9 )  as  usize ; 
255303    let  mut  state = common:: mock_block_accounts ( common:: START_ADDRESS ,  num_eoa) ; 
256304    let  eoa_addresses = state. keys ( ) . cloned ( ) . collect :: < Vec < _ > > ( ) ; 
257305    let  mut  txs = Vec :: with_capacity ( num_native_transfer + num_erc20_transfer + num_uniswap) ; 
258306
259307    for  _ in  0 ..num_native_transfer { 
260-         let  from = Address :: from ( U160 :: from ( 
261-             common:: START_ADDRESS  + get_account_idx ( num_eoa,  hot_start_idx,  hot_ratio) , 
262-         ) ) ; 
263-         let  to = Address :: from ( U160 :: from ( 
264-             common:: START_ADDRESS  + get_account_idx ( num_eoa,  hot_start_idx,  hot_ratio) , 
265-         ) ) ; 
308+         let  from =
309+             Address :: from ( U160 :: from ( common:: START_ADDRESS  + pick_account_idx ( num_eoa,  hot_ratio) ) ) ; 
310+         let  to =
311+             Address :: from ( U160 :: from ( common:: START_ADDRESS  + pick_account_idx ( num_eoa,  hot_ratio) ) ) ; 
266312        let  tx = TxEnv  { 
267313            caller :  from, 
268314            transact_to :  TransactTo :: Call ( to) , 
@@ -280,10 +326,10 @@ fn bench_hybrid(c: &mut Criterion, db_latency_us: u64, num_eoa: usize, hot_ratio
280326    for  ( sca_addr,  _)  in  erc20_contract_accounts. iter ( )  { 
281327        for  _ in  0 ..( num_erc20_transfer / NUM_ERC20_SCA )  { 
282328            let  from = Address :: from ( U160 :: from ( 
283-                 common:: START_ADDRESS  + get_account_idx ( num_eoa,  hot_start_idx ,  hot_ratio) , 
329+                 common:: START_ADDRESS  + pick_account_idx ( num_eoa,  hot_ratio) , 
284330            ) ) ; 
285331            let  to = Address :: from ( U160 :: from ( 
286-                 common:: START_ADDRESS  + get_account_idx ( num_eoa,  hot_start_idx ,  hot_ratio) , 
332+                 common:: START_ADDRESS  + pick_account_idx ( num_eoa,  hot_ratio) , 
287333            ) ) ; 
288334            let  tx = TxEnv  { 
289335                caller :  from, 
@@ -315,7 +361,7 @@ fn bench_hybrid(c: &mut Criterion, db_latency_us: u64, num_eoa: usize, hot_ratio
315361
316362            txs. push ( TxEnv  { 
317363                caller :  Address :: from ( U160 :: from ( 
318-                     common:: START_ADDRESS  + get_account_idx ( num_eoa,  hot_start_idx ,  hot_ratio) , 
364+                     common:: START_ADDRESS  + pick_account_idx ( num_eoa,  hot_ratio) , 
319365                ) ) , 
320366                gas_limit :  uniswap:: GAS_LIMIT , 
321367                gas_price :  U256 :: from ( 0xb2d05e07u64 ) , 
0 commit comments