@@ -126,12 +126,14 @@ struct PathTimings {
126126 fold : Option < Duration > ,
127127}
128128
129- /// Times one operation once (a single observation) when `run` is true, else returns `None`. The result
130- /// is `black_box`-ed so the work is not optimised away.
131- fn timed < T > ( run : bool , operation : impl FnOnce ( ) -> T ) -> Option < Duration > {
129+ /// Times one operation once (a single observation) when `run` is true, else returns `None`. Prints a
130+ /// progress line to stderr **before** starting the clock (so logging is never counted in the timing) and
131+ /// `black_box`-es the result so the work is not optimised away.
132+ fn timed < T > ( label : & str , run : bool , operation : impl FnOnce ( ) -> T ) -> Option < Duration > {
132133 if !run {
133134 return None ;
134135 }
136+ eprintln ! ( " {label} …" ) ;
135137 let start = Instant :: now ( ) ;
136138 black_box ( operation ( ) ) ;
137139 Some ( start. elapsed ( ) )
@@ -147,31 +149,48 @@ fn measure_path(
147149 env : & IvcBenchEnv ,
148150 step : & PreparedStep ,
149151) -> PathTimings {
152+ // Each id doubles as the stderr progress label, so the log line matches the `--list` ids exactly.
153+ let prove_poseidon = {
154+ let id = format ! ( "ivc/{name}/prove/poseidon" ) ;
155+ timed ( & id, selected ( filter, & id) , || {
156+ env. prove_poseidon ( step) . expect ( "poseidon prove should succeed" )
157+ } )
158+ } ;
159+ let prove_blake2b = {
160+ let id = format ! ( "ivc/{name}/prove/blake2b" ) ;
161+ timed ( & id, selected ( filter, & id) , || {
162+ env. prove_blake2b ( step) . expect ( "blake2b prove should succeed" )
163+ } )
164+ } ;
165+ let verify_full = {
166+ let id = format ! ( "ivc/{name}/verify/full" ) ;
167+ timed ( & id, selected ( filter, & id) , || {
168+ env. verify_full ( step) . expect ( "full verification should succeed" )
169+ } )
170+ } ;
171+ let verify_kzg_opening = {
172+ let id = format ! ( "ivc/{name}/verify/kzg_opening" ) ;
173+ timed ( & id, selected ( filter, & id) , || {
174+ env. verify_kzg_opening ( step) . expect ( "kzg opening should succeed" )
175+ } )
176+ } ;
177+ let fold = if is_genesis {
178+ None
179+ } else {
180+ let id = format ! ( "ivc/{name}/fold" ) ;
181+ timed ( & id, selected ( filter, & id) , || {
182+ env. fold_accumulators ( step) . expect ( "non-genesis fold present" )
183+ } )
184+ } ;
185+
150186 PathTimings {
151187 name,
152188 proof_size : step. proof_size ( ) ,
153- prove_poseidon : timed (
154- selected ( filter, & format ! ( "ivc/{name}/prove/poseidon" ) ) ,
155- || env. prove_poseidon ( step) . expect ( "poseidon prove should succeed" ) ,
156- ) ,
157- prove_blake2b : timed (
158- selected ( filter, & format ! ( "ivc/{name}/prove/blake2b" ) ) ,
159- || env. prove_blake2b ( step) . expect ( "blake2b prove should succeed" ) ,
160- ) ,
161- verify_full : timed ( selected ( filter, & format ! ( "ivc/{name}/verify/full" ) ) , || {
162- env. verify_full ( step) . expect ( "full verification should succeed" )
163- } ) ,
164- verify_kzg_opening : timed (
165- selected ( filter, & format ! ( "ivc/{name}/verify/kzg_opening" ) ) ,
166- || env. verify_kzg_opening ( step) . expect ( "kzg opening should succeed" ) ,
167- ) ,
168- fold : if is_genesis {
169- None
170- } else {
171- timed ( selected ( filter, & format ! ( "ivc/{name}/fold" ) ) , || {
172- env. fold_accumulators ( step) . expect ( "non-genesis fold present" )
173- } )
174- } ,
189+ prove_poseidon,
190+ prove_blake2b,
191+ verify_full,
192+ verify_kzg_opening,
193+ fold,
175194 }
176195}
177196
@@ -234,14 +253,20 @@ fn run_path_benches(filter: Option<&str>) {
234253 // One shared environment (a full recursive keygen) for the whole run; `cache` stays in scope (and
235254 // thus on disk) for the entire block. The keygen is timed once as the one-off `setup` cost.
236255 let cache = TempDir :: new ( ) . expect ( "bench cache tempdir" ) ;
256+ eprintln ! ( "building shared environment (recursive keygen); this dominates the runtime …" ) ;
237257 let setup_start = Instant :: now ( ) ;
238258 let env = IvcBenchEnv :: new ( cache. path ( ) ) . expect ( "IVC bench environment should build" ) ;
239259 let setup = setup_start. elapsed ( ) ;
260+ eprintln ! (
261+ "environment ready in {:.1}s; measuring paths …" ,
262+ setup. as_secs_f64( )
263+ ) ;
240264
241265 let rows: Vec < PathTimings > = PATHS
242266 . iter ( )
243267 . filter ( |( path, name) | path_selected ( filter, * path, name) )
244268 . map ( |( path, name) | {
269+ eprintln ! ( "[{name}] preparing fixture (untimed) …" ) ;
245270 let step = env. prepare_step ( * path) . expect ( "fixture preparation should succeed" ) ;
246271 measure_path (
247272 filter,
@@ -268,6 +293,7 @@ fn observe<T>(operation: impl FnOnce() -> T) -> Duration {
268293/// per-path environment.
269294fn run_setup_benches ( filter : Option < & str > ) {
270295 let srs = selected ( filter, "ivc/setup/srs" ) . then ( || {
296+ eprintln ! ( "measuring setup: ivc/setup/srs (cold then warm) …" ) ;
271297 let dir = TempDir :: new ( ) . expect ( "bench cache tempdir" ) ;
272298 let cold = observe ( || {
273299 IvcBenchEnv :: measure_srs_cold_start ( dir. path ( ) ) . expect ( "srs cold-start should succeed" )
@@ -279,8 +305,8 @@ fn run_setup_benches(filter: Option<&str>) {
279305 } ) ;
280306 let keys = selected ( filter, "ivc/setup/keys" ) . then ( || {
281307 eprintln ! (
282- "note: ' ivc/setup/keys' runs a full recursive keygen for the cold measurement \
283- (minutes, GB-scale RAM). "
308+ "measuring setup: ivc/setup/keys (cold then warm) — the cold run does a full recursive \
309+ keygen (minutes, GB-scale RAM) … "
284310 ) ;
285311 let dir = TempDir :: new ( ) . expect ( "bench cache tempdir" ) ;
286312 let srs = IvcBenchEnv :: measure_srs_cold_start ( dir. path ( ) )
0 commit comments