1
+ use std:: collections:: HashMap ;
1
2
use std:: fs:: { self , File } ;
2
3
use std:: io:: Write ;
3
4
use std:: path:: PathBuf ;
4
5
use std:: sync:: atomic:: AtomicU64 ;
5
- use std:: sync:: Arc ;
6
+ use std:: sync:: { Arc , LazyLock , Mutex } ;
6
7
7
8
use cairo_lang_sierra:: program:: Program ;
8
9
use cairo_lang_starknet_classes:: compiler_version:: VersionId ;
@@ -12,11 +13,26 @@ use cairo_native::executor::AotContractExecutor;
12
13
use cairo_native:: starknet:: StarknetSyscallHandler ;
13
14
use cairo_native:: utils:: BuiltinCosts ;
14
15
use itertools:: Itertools ;
16
+ use serde:: Serialize ;
15
17
use sierra_emu:: VirtualMachine ;
16
18
use starknet_types_core:: felt:: Felt ;
17
19
18
20
use super :: syscall_handler:: NativeSyscallHandler ;
19
21
22
+ #[ cfg( feature = "with-libfunc-profiling" ) ]
23
+ #[ derive( Debug , Serialize ) ]
24
+ pub struct ProfilerResults {
25
+ pub libfunc_idx : u64 ,
26
+ pub samples : u64 ,
27
+ pub total_time : u64 ,
28
+ pub average_time : f64 ,
29
+ pub std_deviation : f64 ,
30
+ pub quartiles : [ u64 ; 5 ] ,
31
+ }
32
+
33
+ pub static LIBFUNC_PROFILES_MAP : LazyLock < Mutex < HashMap < Felt , Vec < ProfilerResults > > > > =
34
+ LazyLock :: new ( || Mutex :: new ( HashMap :: new ( ) ) ) ;
35
+
20
36
#[ derive( Debug ) ]
21
37
pub enum ContractExecutor {
22
38
Aot ( AotContractExecutor ) ,
@@ -176,22 +192,28 @@ impl ContractExecutor {
176
192
// Retreive trace dump for current execution
177
193
let profile = LIBFUNC_PROFILE . lock ( ) . unwrap ( ) . remove ( & counter) . unwrap ( ) ;
178
194
179
- // Save trace dump to file
180
- let profile_path = PathBuf :: from ( format ! ( "libfunc_profiles/{counter}.md" ) ) ;
181
- let profile_parent_path = profile_path. parent ( ) . unwrap ( ) ;
182
- fs:: create_dir_all ( profile_parent_path) . unwrap ( ) ;
183
- let mut profile_file = File :: create ( & profile_path) . unwrap ( ) ;
184
-
185
195
for ( libfunc_id, ( n_samples, sum, quartiles, average, std_dev) ) in
186
196
profile. process ( )
187
197
{
188
- writeln ! ( profile_file, "{libfunc_id}" ) ?;
189
- writeln ! ( profile_file, " Total Samples: {n_samples}" ) ?;
190
- writeln ! ( profile_file, " Total Execution Time: {sum}" ) ?;
191
- writeln ! ( profile_file, " Average Execution Time: {average}" ) ?;
192
- writeln ! ( profile_file, " Standard Deviation: {std_dev}" ) ?;
193
- writeln ! ( profile_file, " Quartiles: {quartiles:?}" ) ?;
194
- writeln ! ( profile_file) ?;
198
+ let profile_result = ProfilerResults {
199
+ libfunc_idx : libfunc_id. id ,
200
+ samples : n_samples,
201
+ total_time : sum,
202
+ average_time : average,
203
+ std_deviation : std_dev,
204
+ quartiles,
205
+ } ;
206
+
207
+ let mut profiles_map = LIBFUNC_PROFILES_MAP . lock ( ) . unwrap ( ) ;
208
+
209
+ match profiles_map. get_mut ( & selector) {
210
+ Some ( profiles) => {
211
+ profiles. push ( profile_result) ;
212
+ }
213
+ None => {
214
+ profiles_map. insert ( selector, vec ! [ profile_result] ) ;
215
+ }
216
+ }
195
217
}
196
218
197
219
* libfunc_profiling_trace_id = libfunc_profiling_old_trace_id;
0 commit comments