@@ -12,33 +12,39 @@ struct Counters {
12
12
cache_references : Counter ,
13
13
}
14
14
15
- /// Benchmarks a single function.
16
- pub fn benchmark_function < F : FnOnce ( ) -> R , R > (
15
+ /// Benchmarks a single function generated by `benchmark_constructor` .
16
+ pub fn benchmark_function < F : Fn ( ) -> Bench + ' static , R , Bench : FnOnce ( ) -> R + ' static > (
17
17
name : & ' static str ,
18
- func : F ,
18
+ benchmark_constructor : F ,
19
19
) -> anyhow:: Result < BenchmarkResult > {
20
20
let mut group = create_group ( ) ?;
21
21
let counters = prepare_counters ( & mut group) ?;
22
22
23
- // FIXME: don't run perf counters and time measurements together, run the benchmark twice
24
- // instead.
25
- let start = Instant :: now ( ) ;
23
+ // Measure perf. counters.
24
+ let func = benchmark_constructor ( ) ;
26
25
27
26
// Do not act on the return value to avoid including the branch in the measurement
28
27
let enable_ret = group. enable ( ) ;
29
28
let output = func ( ) ;
30
29
group. disable ( ) ?;
31
30
32
- let duration = start. elapsed ( ) ;
31
+ // Try to avoid optimizing the result out
32
+ black_box ( output) ;
33
33
34
34
// Check if we have succeeded before
35
35
enable_ret?;
36
36
37
+ let measurement = group. read ( ) ?;
38
+
39
+ // Measure wall time.
40
+ let func = benchmark_constructor ( ) ;
41
+
42
+ let start = Instant :: now ( ) ;
43
+ let output = func ( ) ;
44
+ let duration = start. elapsed ( ) ;
37
45
// Try to avoid optimizing the result out
38
46
black_box ( output) ;
39
47
40
- let measurement = group. read ( ) ?;
41
-
42
48
let result = BenchmarkResult {
43
49
name : String :: from ( name) ,
44
50
cycles : measurement[ & counters. cycles ] ,
0 commit comments