@@ -10,12 +10,16 @@ use std::sync::Arc;
1010use allocator as _;
1111use criterion:: { Criterion , Throughput } ;
1212use easy_ext:: ext;
13- use eth2_cache_utils:: { goerli, mainnet, medalla, LazyBeaconBlocks , LazyBeaconState } ;
13+ use eth2_cache_utils:: {
14+ goerli, mainnet, medalla, LazyBeaconBlocks , LazyBeaconState , LazyBlobSidecars ,
15+ } ;
1416use itertools:: Itertools as _;
15- use ssz:: { SszRead as _, SszWrite as _} ;
17+ use serde:: { Deserialize , Serialize } ;
18+ use ssz:: { SszRead , SszWrite } ;
1619use types:: {
1720 combined:: { BeaconState , SignedBeaconBlock } ,
1821 config:: Config ,
22+ deneb:: containers:: BlobSidecar ,
1923 preset:: Preset ,
2024} ;
2125
@@ -73,6 +77,10 @@ fn main() {
7377 & Config :: medalla ( ) ,
7478 & medalla:: BEACON_BLOCKS_UP_TO_SLOT_128 ,
7579 )
80+ . benchmark_blob_sidecars (
81+ "mainnet Deneb blob sidecars from 32 slots" ,
82+ & mainnet:: DENEB_BLOB_SIDECARS_FROM_32_SLOTS ,
83+ )
7684 . final_summary ( ) ;
7785}
7886
@@ -120,35 +128,82 @@ impl Criterion {
120128 config : & Config ,
121129 blocks : & LazyBeaconBlocks < P > ,
122130 ) -> & mut Self {
123- let ssz_bytes = LazyCell :: new ( || blocks_to_ssz ( blocks. force ( ) ) ) ;
124- let json_bytes = LazyCell :: new ( || blocks_to_json_directly ( blocks. force ( ) ) ) ;
131+ let ssz_bytes = LazyCell :: new ( || slice_to_ssz ( blocks. force ( ) ) ) ;
132+ let json_bytes = LazyCell :: new ( || slice_to_json_directly ( blocks. force ( ) ) ) ;
125133
126134 self . benchmark_group ( group_name)
127135 . throughput ( Throughput :: Elements ( blocks. count ( ) ) )
128136 . bench_function ( "from SSZ" , |bencher| {
129137 let ssz_bytes = ssz_bytes. iter ( ) . map ( Vec :: as_slice) ;
130138
131- bencher. iter_with_large_drop ( || blocks_from_ssz :: < P > ( config, ssz_bytes. clone ( ) ) )
139+ bencher. iter_with_large_drop ( || {
140+ vec_from_ssz :: < Config , Arc < SignedBeaconBlock < P > > > ( config, ssz_bytes. clone ( ) )
141+ } )
132142 } )
133143 . bench_function ( "to SSZ" , |bencher| {
134144 let blocks = blocks. force ( ) ;
135145
136- bencher. iter_with_large_drop ( || blocks_to_ssz ( blocks) )
146+ bencher. iter_with_large_drop ( || slice_to_ssz ( blocks) )
137147 } )
138148 . bench_function ( "from JSON" , |bencher| {
139149 let json_bytes = json_bytes. iter ( ) . map ( Vec :: as_slice) ;
140150
141- bencher. iter_with_large_drop ( || blocks_from_json :: < P > ( json_bytes. clone ( ) ) )
151+ bencher. iter_with_large_drop ( || {
152+ vec_from_json :: < Arc < SignedBeaconBlock < P > > > ( json_bytes. clone ( ) )
153+ } )
142154 } )
143155 . bench_function ( "to JSON directly" , |bencher| {
144156 let blocks = blocks. force ( ) ;
145157
146- bencher. iter_with_large_drop ( || blocks_to_json_directly ( blocks) )
158+ bencher. iter_with_large_drop ( || slice_to_json_directly ( blocks) )
147159 } )
148160 . bench_function ( "to JSON via serde_utils::stringify" , |bencher| {
149161 let blocks = blocks. force ( ) ;
150162
151- bencher. iter_with_large_drop ( || blocks_to_json_via_stringify ( blocks) )
163+ bencher. iter_with_large_drop ( || slice_to_json_via_stringify ( blocks) )
164+ } ) ;
165+
166+ self
167+ }
168+
169+ fn benchmark_blob_sidecars < P : Preset > (
170+ & mut self ,
171+ group_name : & str ,
172+ blob_sidecars : & LazyBlobSidecars < P > ,
173+ ) -> & mut Self {
174+ let ssz_bytes = LazyCell :: new ( || slice_to_ssz ( blob_sidecars. force ( ) ) ) ;
175+ let json_bytes = LazyCell :: new ( || slice_to_json_directly ( blob_sidecars. force ( ) ) ) ;
176+
177+ self . benchmark_group ( group_name)
178+ . throughput ( Throughput :: Elements ( blob_sidecars. count ( ) ) )
179+ . bench_function ( "from SSZ" , |bencher| {
180+ let ssz_bytes = ssz_bytes. iter ( ) . map ( Vec :: as_slice) ;
181+
182+ bencher. iter_with_large_drop ( || {
183+ vec_from_ssz :: < ( ) , Arc < BlobSidecar < P > > > ( & ( ) , ssz_bytes. clone ( ) )
184+ } )
185+ } )
186+ . bench_function ( "to SSZ" , |bencher| {
187+ let blob_sidecars = blob_sidecars. force ( ) ;
188+
189+ bencher. iter_with_large_drop ( || slice_to_ssz ( blob_sidecars) )
190+ } )
191+ . bench_function ( "from JSON" , |bencher| {
192+ let json_bytes = json_bytes. iter ( ) . map ( Vec :: as_slice) ;
193+
194+ bencher. iter_with_large_drop ( || {
195+ vec_from_json :: < Arc < BlobSidecar < P > > > ( json_bytes. clone ( ) )
196+ } )
197+ } )
198+ . bench_function ( "to JSON directly" , |bencher| {
199+ let blob_sidecars = blob_sidecars. force ( ) ;
200+
201+ bencher. iter_with_large_drop ( || slice_to_json_directly ( blob_sidecars) )
202+ } )
203+ . bench_function ( "to JSON via serde_utils::stringify" , |bencher| {
204+ let blob_sidecars = blob_sidecars. force ( ) ;
205+
206+ bencher. iter_with_large_drop ( || slice_to_json_via_stringify ( blob_sidecars) )
152207 } ) ;
153208
154209 self
@@ -175,47 +230,46 @@ fn state_to_json_via_stringify(state: &BeaconState<impl Preset>) -> Vec<u8> {
175230 . expect ( "state should be serializable to JSON" )
176231}
177232
178- fn blocks_from_ssz < ' bytes , P : Preset > (
179- config : & Config ,
233+ fn vec_from_ssz < ' bytes , C , T : SszRead < C > > (
234+ context : & C ,
180235 bytes : impl IntoIterator < Item = & ' bytes [ u8 ] > ,
181- ) -> Vec < Arc < SignedBeaconBlock < P > > > {
236+ ) -> Vec < T > {
182237 bytes
183238 . into_iter ( )
184- . map ( |bytes| Arc :: from_ssz ( config , bytes) )
239+ . map ( |bytes| T :: from_ssz ( context , bytes) )
185240 . try_collect ( )
186- . expect ( "blocks have already been successfully deserialized" )
241+ . expect ( "iterator items have already been successfully deserialized from SSZ " )
187242}
188243
189- fn blocks_to_ssz ( blocks : & [ Arc < SignedBeaconBlock < impl Preset > > ] ) -> Vec < Vec < u8 > > {
190- blocks
191- . iter ( )
192- . map ( Arc :: to_ssz)
193- . try_collect ( )
194- . expect ( "blocks can be serialized because they have already been serialized to a file" )
244+ fn slice_to_ssz ( slice : & [ impl SszWrite ] ) -> Vec < Vec < u8 > > {
245+ slice. iter ( ) . map ( SszWrite :: to_ssz) . try_collect ( ) . expect (
246+ "slice elements can be serialized to SSZ because \
247+ they have already been serialized to a file",
248+ )
195249}
196250
197- fn blocks_from_json < ' bytes , P : Preset > (
251+ fn vec_from_json < ' bytes , T : Deserialize < ' bytes > > (
198252 bytes : impl IntoIterator < Item = & ' bytes [ u8 ] > ,
199- ) -> Vec < Arc < SignedBeaconBlock < P > > > {
253+ ) -> Vec < T > {
200254 bytes
201255 . into_iter ( )
202256 . map ( serde_json:: from_slice)
203257 . try_collect ( )
204- . expect ( "blocks should be deserializable from JSON" )
258+ . expect ( "iterator items should be deserializable from JSON" )
205259}
206260
207- fn blocks_to_json_directly ( blocks : & [ Arc < SignedBeaconBlock < impl Preset > > ] ) -> Vec < Vec < u8 > > {
208- blocks
261+ fn slice_to_json_directly ( slice : & [ impl Serialize ] ) -> Vec < Vec < u8 > > {
262+ slice
209263 . iter ( )
210264 . map ( serde_json:: to_vec)
211265 . try_collect ( )
212- . expect ( "blocks should be serializable to JSON" )
266+ . expect ( "slice elements should be serializable to JSON" )
213267}
214268
215- fn blocks_to_json_via_stringify ( blocks : & [ Arc < SignedBeaconBlock < impl Preset > > ] ) -> Vec < Vec < u8 > > {
216- blocks
269+ fn slice_to_json_via_stringify ( slice : & [ impl Serialize ] ) -> Vec < Vec < u8 > > {
270+ slice
217271 . iter ( )
218- . map ( |block | serde_utils:: stringify ( block ) . and_then ( |json| serde_json:: to_vec ( & json) ) )
272+ . map ( |element | serde_utils:: stringify ( element ) . and_then ( |json| serde_json:: to_vec ( & json) ) )
219273 . try_collect ( )
220- . expect ( "blocks should be serializable to JSON" )
274+ . expect ( "slice elements should be serializable to JSON" )
221275}
0 commit comments