@@ -5,6 +5,7 @@ use crate::{
55 plugins:: { alloc:: * , * } ,
66 stats:: * ,
77} ;
8+ use quanta:: Instant ;
89
910/// The trait which typically wraps a InputWithBenchmark and allows to hide the generics.
1011pub trait Bench < ' a > {
@@ -183,7 +184,7 @@ impl<'a, I, O: OutputValue> NamedBench<'a, I, O> {
183184 const TARGET_NS_PER_BENCH : u128 = TARGET_MS_PER_BENCH as u128 * 1_000_000 ;
184185 {
185186 // Preliminary test if function is very slow
186- let start = std :: time :: Instant :: now ( ) ;
187+ let start = Instant :: now ( ) ;
187188 #[ allow( clippy:: unit_arg) ]
188189 black_box ( ( self . fun ) ( input) ) ;
189190 let elapsed_ms = start. elapsed ( ) . as_millis ( ) as u64 ;
@@ -192,7 +193,7 @@ impl<'a, I, O: OutputValue> NamedBench<'a, I, O> {
192193 }
193194 }
194195
195- let start = std :: time :: Instant :: now ( ) ;
196+ let start = Instant :: now ( ) ;
196197 for _ in 0 ..64 {
197198 #[ allow( clippy:: unit_arg) ]
198199 black_box ( ( self . fun ) ( input) ) ;
@@ -217,18 +218,24 @@ impl<'a, I, O: OutputValue> NamedBench<'a, I, O> {
217218 bench_id : & self . bench_id ,
218219 } ) ;
219220 debug_assert ! ( num_iter > 0 ) ;
220- let start = std:: time:: Instant :: now ( ) ;
221221
222222 // Defer dropping outputs so destructor cost is not part of the measured time.
223223 let run_result = if O :: defer_drop ( ) {
224- let mut outputs: Vec < O > = Vec :: with_capacity ( num_iter) ;
224+ let mut sum_ns = 0u64 ;
225+ let mut res: Option < O > = None ;
226+ // In this mode, we measure each iteration separately to avoid destructor cost.
227+ // There may be some overhead, but it should be outweighed by benchmarks that allocate
225228 for _ in 0 ..num_iter {
226- outputs. push ( black_box ( ( self . fun ) ( input) ) ) ;
229+ res. take ( ) ;
230+ let start = Instant :: now ( ) ;
231+ let val = black_box ( ( self . fun ) ( input) ) ;
232+ sum_ns += start. elapsed ( ) . as_nanos ( ) as u64 ;
233+ res = Some ( val) ;
227234 }
228- let duration_ns = start. elapsed ( ) . as_nanos ( ) as u64 / num_iter as u64 ;
229- let last_output = outputs. pop ( ) . expect ( "num_iter > 0" ) ;
230- RunResult :: new ( duration_ns, last_output)
235+ let duration_ns = sum_ns / num_iter as u64 ;
236+ RunResult :: new ( duration_ns, res. unwrap ( ) )
231237 } else {
238+ let start = Instant :: now ( ) ;
232239 let mut res: Option < O > = None ;
233240 for _ in 0 ..num_iter {
234241 res = Some ( black_box ( ( self . fun ) ( input) ) ) ;
0 commit comments