1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use std::{sync::atomic::AtomicU64, time::Instant};
use strum::IntoEnumIterator;
use strum_macros::EnumIter;

use fixed_map::{Key, Map};
use once_cell::sync::Lazy;

#[derive(Clone, Copy, Key, EnumIter, Debug)]
pub enum PerfParts {
    UniqueMoves,
    UniqueMovesDouble,
    UniqueMovesNormalDice,

    UniqueOneDie,
    OneDie,

    // one die:
    Bar,
    Removals,
    Calc,
    GenBoards,
}

pub static PERF_MAP: Lazy<Map<PerfParts, AtomicU64>> = Lazy::new(|| {
    let mut m = Map::new();
    for v in PerfParts::iter() {
        m.insert(v, AtomicU64::new(0));
    }
    m
});

#[cfg(feature = "time")]
#[inline(always)]
pub fn time<T>(key: PerfParts, f: impl FnOnce() -> T) -> T {
    let now = Instant::now();

    let result = f();

    let elapsed = now.elapsed().as_nanos() as u64;

    (*PERF_MAP)
        .get(key)
        .unwrap()
        .fetch_add(elapsed, std::sync::atomic::Ordering::Relaxed);

    result
}

#[cfg(not(feature = "time"))]
#[inline(always)]
pub fn time<T>(_key: PerfParts, f: impl FnOnce() -> T) -> T {
    f()
}